2

I need to convert a .tiff image to a bitmap one without saving the bitmap. I know that I should use GDAL_translate but because I'm new, this function's interface is a little complicated for me. Could you please tell me how should I call the function in this special case?
And if you have any better suggestion than using GDAL_translate, please allow me be informed?

Note that I don't want to save the bitmap. It's just for displaying purposes in mfc and my superior has told me not to save the bitmap just convert data to bitmap at run-time.

well @user1240592,@Mapperz,@Alex Marcov,@Jamo,@Tonny,@johanvdw and @soheil I've seen the question you've answered here. my problem is I don't need a bitmap file to be created on the hard disk. suppose that I have this MFC application enter image description here already I have written the code to print header information of a geotiff in the rich edit box now I need something to convert a 15931x16997 geotiff to bitmap at runtime and show it in a picture control ( I need a high performance way) and be able to do various image processing operations on this bitmap data at run-time (using opencv) and immediately show the result on the picture control and also be able to do these tasks when the image is viewed:
1-zoom in
2-zoom out 3-pan 4-fixed zoom in 5-fixed zoom out 6-go back to previous extent
7-go next extent
and then if needed I can convert the bitmap data created by image processing operations to a geotiff image file and convert it in the hard disk.
I don't have problems with image processing parts,opening and saving geotiff images, extracting raster data and write raster data.
my problem is converting data to bitmap at runtime and use a high performance way (like openGL) to display the image with high performance and do various navigation tasks on it.
Do you anyway or any library that have implemented these tasks Notice just need bitmap data on the buffer not saved on the hard disk?

  • Has any find solution for your question? I need same solution ... – echoloji Jan 18 '16 at 11:46
  • This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. You can also add a bounty to draw more attention to this question once you have enough reputation. - From Review – Evil Genius Jan 18 '16 at 12:51
  • Yes I actually know that is not really answer. I have already asked a question in this link . But There is no answer so I would like to ask to solve here. – echoloji Jan 18 '16 at 12:57
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient reputation you will be able to comment on any post. - From Review – MerseyViking Jan 18 '16 at 14:33
  • @echoloji this has been about two and a half years. Surely I solved the problem that time and I submitted the project to my boss but I can't remember. Maybe I can have a look to my project to see how I solved it but I don't promise. But if you are in a hurry you can start a bounty on this question or your own question in 2 days to drive some attention and get your question answered. – Sepideh Abadpour Jan 18 '16 at 16:04
1

gdal_translate is a command line executable. In your C++ code you could use the system() function to call it, but it will always save the output to disk.

What you need to do is read up on the GDAL C++ API and the API Tutorial.

1

The answer to the question is there's no need to convert the data to a bitmap format at run time. You can pass the data obtained by the RasterIO function to your opencv functions.
This question is for when I worked in a company as an apprentice. The time when I didn't know anything about GDAL. So I've asked the question generally and it did not receive much attention.
Here I give some guidelines about GDAL functions in a hypothetical project and the next visitors of the question should ask their own specific questions here or in other stackexchange sites like stackoverflow or game developement.
Because operations like panning and zooming is not related to GDAL library at all. It's related to OpenGL or other Graphical interfaces you have chosen for your project.

Suppose that you have a project where you should open and show a geotiff image, do some image processing operations on it and then save the result.

First of all for opening the geotiff file you should create a pointer to object of the class GDALDataset like the following.

GDALDataset *poDataset;

Create these variables to store different characters of this data set like the digital numbers of the pixels, etc.

int RasterXSize;
int RasterYSize;
int RasterCount;
int BytesPerPixel;
GDALDataType eType;
vector<unsigned char>pRasterData;  

To open the file call the GDALOpen and store the address of the returned variable in your GDALDataset pointer:

poDataset = (GDALDataset*)GDALOpen(ascii.m_psz,GA_ReadOnly);  

Now you can obtain various characteristics of the data from this pointer:

RasterXSize = poDataset -> GetRasterXSize();
RasterYSize = poDataset -> GetRasterYSize();
RasterCount = poDataset -> GetRasterCount();
GDALRasterBand *poRasterBand;
poRasterBand = poDataset -> GetRasterBand(1);
eType = poRasterBand -> GetRasterDataType();
BytesPerPixel = GDALGetDataTypeSize(eType)/8;  

To read the header of geotiff you should call various functions on this pointer. Here I've added the code for a function that uses GDAL library to read the header of geotiff and returns the information as a string which you can display in the console or in a text box on your MFC dialog.

CString ManageOpenGeoTiffFiles::ReadGeoTiffHeader()
{
    double adfGeoTransform[6];
    char* bufferTitle = "Image header information:\n";
    char* buffer1 = new char[50];
    sprintf(buffer1,"Driver: %s/%s\n",poDataset->GetDriver()->GetDescription(),poDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME));
    char* buffer2 = new char[50];
    sprintf(buffer2,"Size is %dx%dx%d\n",poDataset->GetRasterXSize(),poDataset->GetRasterYSize(),poDataset->GetRasterCount());
    char* buffer3 = new char[1000];
    if( poDataset->GetProjectionRef()!= NULL )
        sprintf(buffer3,"Projection is `%s'\n",poDataset->GetProjectionRef());
    else
        buffer3 = "Projection is not specified.\n";
    char* buffer4 = new char[50];
    char* buffer5 = new char[50];
    char* buffer6 = new char[50];
    if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None )
    {
        sprintf(buffer4,"Origin = (%.6f,%.6f)\n",adfGeoTransform[0],adfGeoTransform[3]);
        sprintf(buffer5,"Pixel Size = (%.6f,%.6f)\n",adfGeoTransform[1],adfGeoTransform[5]);
        sprintf(buffer6,"Rotation relative to north = (%.6f,%.6f)\n",adfGeoTransform[2],adfGeoTransform[4]);
    }
    else
    {
        buffer4 = "Geotransform parameters are not specified.";
    }
    CA2T TbufferTitle(bufferTitle);
    CA2T Tbuffer1(buffer1);
    CA2T Tbuffer2(buffer2);
    CA2T Tbuffer3(buffer3);
    CA2T Tbuffer4(buffer4);
    CA2T Tbuffer5(buffer5);
    CA2T Tbuffer6(buffer6);
    CString StringbufferTitle = TbufferTitle.m_psz;
    CString Stringbuffer1 = Tbuffer1.m_psz;
    CString Stringbuffer2 = Tbuffer2.m_psz;
    CString Stringbuffer3 = Tbuffer3.m_psz;
    CString Stringbuffer4 = Tbuffer4.m_psz;
    CString Stringbuffer5 = Tbuffer5.m_psz;
    CString Stringbuffer6 = Tbuffer6.m_psz;
    CString headerInfo = StringbufferTitle + Stringbuffer1 + Stringbuffer2 + Stringbuffer3 + Stringbuffer4 + Stringbuffer5 + Stringbuffer6;
    delete buffer1;
    delete buffer2;
    delete buffer3;
    delete buffer4;
    delete buffer5;
    delete buffer6;
    return headerInfo;
}  

Now read the DNs of pixels and store it in the vector that you created earlier:

pRasterData.resize(RasterXSize * RasterYSize * RasterCount * BytesPerPixel);
CPLErr error = poDataset -> RasterIO(GF_Read,0,0,RasterXSize,RasterYSize,&pRasterData[0],RasterXSize,RasterYSize,eType,RasterCount,0,0,0,0);  

Notice the declaration of the RasterIO function, you will store the data in an array which is passed as a pointer to the function. This is a common operation in C++ language. You will use this vector of data in the next step where you should apply a Gaussian filter to the image with the help of OpenCV library. Create two instances of the class Mat in OpenCV and use the information you obtained above to store image data in one of these instances. Apply the filter and store the result in an array:

cv::Mat img1(RasterYSize,RasterXSize,CV_8UC1,&pRasterData[0]);
    cv::Mat img2;
    cv::GaussianBlur(img1,img2,cv::Size(5,5),1);
    OpenCVGaussian = img2.reshape(1,1);
    pRasterDataOut = OpenCVGaussian;  

As you see there's no need to convert the data to a bitmap to be able to manipulate it in OpenCV. You can pass the data obtained by GDAL library as an array to the OpenCV library and use the functionalities of both libraries.
You can now assign the vector generated by the OpenCVGaussian function to another pointer of the class GDALDataset and store the data in a file. Finally you can close both files.
First of all create a geotiff format file and open it a writable to be able to write the data on it

const char *fileFormat = "GTiff";
GDALDriver *poDriver;
char **pofileMetadata;
poDriver = GetGDALDriverManager()->GetDriverByName(fileFormat); 
pofileMetadata = poDriver->GetMetadata();
CT2A ascii( filepath );
char **pofileOptions = NULL;
poDatasetOut = poDriver->Create( ascii.m_psz, RasterXSize, RasterYSize, RasterCount, eType, pofileOptions );  

pass the pointer to the vector poRasterDataOut to the RasterIO called on the pointer poDatasetOut of the class GDALDataset created earlier by the Create function of the class GDALDriver

CPLErr error = poDatasetOut -> RasterIO(GF_Write,0,0,RasterXSize,RasterYSize,&pRasterDataOut[0],RasterXSize,RasterYSize,eType,RasterCount,0,0,0,0); 

Write the header of this file by calling functions like SetGeoTransform and SetProjection on this output pointer of the class GDALDataset and finally close the two files

GDALClose( (GDALDatasetH) m_saveFiles.poDatasetOut);
GDALClose( (GDALDatasetH) m_openFiles.poDataset);  

Remember to add the following in the initialization code of your MFC Dialog to be able to use GDAL library.

GDALAllRegister();  

To add functionalities like zoom in, zoom out, pan, full extent to your program, you should be able to work with the OpenGL library. To start I recommend the class Setting Up OpenGL in an MFC Control. Use your programming knowledge and customize this class for your own needs.
Use your object oriented programming knowledge to connect objects of three major classes

  • A class of OpenGL library for displaying capabilities
  • A class of OpenCV library for manipulating capabilities
  • A class of GDAL library for reading and writing data from and to geospatial formats

in your program and add fantastic functionalities to your software.

Here's the code of a class used to set up OpenGL in MFC control

0

If you are using gdal_translate as a command-line function, like in FWTools, this would be the operation: gdal_translate -of BMP c:\temp\input.tif c:\temp\output.bmp

You could also use QGIS. Under the Raster tab, Conversion, there is the Translate tool

  • Oh no I want to use it as a function in my c++ code @Ryan Garnett – Sepideh Abadpour Aug 1 '13 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.