tiff或tif文件的读取
生活随笔
收集整理的這篇文章主要介紹了
tiff或tif文件的读取
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
以下是VC下讀取TIFF文件的代碼
char* szFileName = "K:\地圖\fujian-DEM\fujian1.tif";
TIFF* tiff = TIFFOpen(szFileName, "r");//打開Tiff文件,得到指針,以后所有的操作都通過指針進行
int nTotalFrame = TIFFNumberOfDirectories(tiff); //得到圖像的總幀數
//TIFFSetDirectory(tiff,0);
//我們打開第一幅圖,也就是第0幀,如果是第1幀,第二個參數寫1,由此類推。因為Windows下圖像基本
//操作都是以BMP格式進行,我們讀出該幀并轉成BMP格式。
char *dtitle;
TIFFGetField(tiff,TIFFTAG_PAGENAME,&dtitle);
//得到該幀的名字,存放在dtitle中。
int width,height;
TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width); //得到寬度
TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height);//得到高度
float resolution = max(width,height);
uint16 bitspersample = 1;
uint16 samplesperpixel = 1;
TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
//每個像素占多少機器字,24位圖samplesperpixel應該等于3。
TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitspersample);
//每一個機器字長,這里應為8。
uint16 bitsperpixel = bitspersample * samplesperpixel;
//算出每個像素占多少bit,24位圖,值為24
DWORD dwBytePerLine = (width*bitsperpixel+31)/32 *4;
//由上面幾個參數算出圖像每行所占字節(BYTE)數。
DWORD64 dwLeng = height*dwBytePerLine;//在內存里存放這幀圖像數據所需要的長度
BYTE* pData = new BYTE[dwLeng]; //為存放數據分配內存空間
uint32* raster;
uint32 *row;
raster = (uint32*)malloc(width * height * sizeof (uint32));
TIFFReadRGBAImage(tiff, width, height, (uint32*)pData, 1);
//以上幾行讀出該幀數據,保存到raster中。
row = &raster[0];
LPBYTE bits2 = pData;
for (int y = 0; y < height; y++)
{
LPBYTE bits = bits2;
for (int x = 0; x < width; x++)
{
*bits++ = (BYTE)TIFFGetB(row[x]);
*bits++ = (BYTE)TIFFGetG(row[x]);
*bits++ = (BYTE)TIFFGetR(row[x]);
}
row += width;
bits2 += dwBytePerLine;
}
_TIFFfree(raster);
//因為Tif的數據存放順序和Windows下的BMP相反,上面這幾句進行轉換。
//轉換結束后,數據存在pData里,釋放raster所用內存。
LPBITMAPINFO pInfo = new BITMAPINFO;
pInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pInfo->bmiHeader.biWidth = width;
pInfo->bmiHeader.biHeight = width;
pInfo->bmiHeader.biCompression = BI_RGB;
pInfo->bmiHeader.biClrUsed = 0;
pInfo->bmiHeader.biClrImportant = 0;
pInfo->bmiHeader.biPlanes = 1;
pInfo->bmiHeader.biBitCount = 24;
pInfo->bmiHeader.biSizeImage = dwLeng;
float xres,yres;
uint16 res_unit;
//解析度單位:如是英寸,厘米
TIFFGetFieldDefaulted(tiff, TIFFTAG_RESOLUTIONUNIT, &res_unit);
if(TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &xres) == 0)
{
pInfo->bmiHeader.biXPelsPerMeter = 0;
}
else
{
if(res_unit == 2) //英寸
{
pInfo->bmiHeader.biXPelsPerMeter = xres * 10000 / 254;
}
else if(res_unit == 3) //厘米
{
pInfo->bmiHeader.biXPelsPerMeter = xres * 100;
}
else
{
pInfo->bmiHeader.biXPelsPerMeter = 0;
}
}
//得到該幀TIFF橫向解析度,并計算出m_pInfo->bmiHeader.biXPelsPerMeter
if(TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &yres) == 0)
{
pInfo->bmiHeader.biYPelsPerMeter = 0;
}
else
{
if(res_unit == 2) //英寸
{
pInfo->bmiHeader.biYPelsPerMeter = yres * 10000 / 254;
}
else if(res_unit == 3) //厘米
{
pInfo->bmiHeader.biYPelsPerMeter = yres * 100;
}
else
{
pInfo->bmiHeader.biYPelsPerMeter = 0;
}
}
//得到該幀TIFF縱向解析度,并計算出m_pInfo->bmiHeader.biYPelsPerMeter
BITMAPFILEHEADER bmheader;
bmheader.bfType=0x4d42;
bmheader.bfSize=0;
bmheader.bfReserved1=0;
bmheader.bfReserved2=0;
bmheader.bfOffBits=54;
//這幾句是生成bmp文件的頭結構
CFile bmpFile;
bmpFile.Open(_T("c://test.bmp"),CFile::modeCreate|CFile::modeWrite);
bmpFile.Write(&bmheader,sizeof(BITMAPFILEHEADER));
bmpFile.Write(&(pInfo->bmiHeader),sizeof(BITMAPINFOHEADER));
bmpFile.Write(pData,dwLeng);
bmpFile.Close();
//這里,把該幀TIFF保存到了C盤的test.bmp中,可以用看圖軟件打開瀏覽一下。
//記得釋放內存空間
delete pInfo;
pInfo = NULL;
delete pData;
pData = NULL;
//如果想直接顯示,就不需要釋放,調用StretchDIBits在客戶區的DC上就可以顯示了。
//如果再打開其他幀的話,從TIFFSetDirectory開始循環運行,比如取下一幀就是
TIFFSetDirectory(tiff,1);
//記得保存時另換一個bmp文件名。
//最后,對這個TIFF文件全部操作結束,記得調用
TIFFClose(tiff);
下面的代碼是用GDAL打開的
char* szFileName = "K:\地圖\fujian-DEM\fujian1.tif";
GDALDataset *poDataset; //GDAL數據集
GDALAllRegister();
poDataset = (GDALDataset*)GDALOpen(szFileName,GA_ReadOnly);
if( poDataset == NULL )
{
AfxMessageBox(_T("文件打開失敗!!!"));
return;
}
GDALRasterBand *poBand; //遙感的一個波段
int nBandCount = poDataset->GetRasterCount();
poBand = poDataset->GetRasterBand(1); //和數組下標有點不同
//獲得圖像顯示窗口的尺寸
GetClientRect(&m_ViewRect);
int nImgSizeX = poDataset->GetRasterXSize();
int nImgSizeY = poDataset->GetRasterYSize();
double adfGeoTransform[6];
poDataset->GetGeoTransform( adfGeoTransform );
double right = adfGeoTransform[0] + nImgSizeX*adfGeoTransform[1];
double bottom = adfGeoTransform[3] + nImgSizeY*adfGeoTransform[5];
int nBufferSizeX,nBufferSizeY;
nBufferSizeX = nImgSizeX;
nBufferSizeY = nImgSizeY;
int nScrrenWidth = m_ViewRect.Width();
int nScrrenHeight= m_ViewRect.Height();
BYTE *pafScanblock1,*TempLock1;
pafScanblock1 = (BYTE *) CPLMalloc((nScrrenWidth)*(nScrrenHeight));
TempLock1 = pafScanblock1;
poBand->RasterIO( GF_Read, 0, 0,nBufferSizeX,nBufferSizeY,
pafScanblock1,nScrrenWidth,nScrrenHeight, GDT_Byte,0, 0 );
//在View逐點顯示圖像
DWORD dwBytes = (nScrrenWidth * 24) / 8;
while(((DWORD) dwBytes) % 4)
{
dwBytes++;
}
BYTE *szBuffer = new BYTE[nScrrenHeight*dwBytes];
memset(szBuffer,0,nScrrenHeight*dwBytes);
BYTE *pTemp = szBuffer;
CClientDC dc(this);
int nIndex = 0;
for (int i=0;i<nScrrenHeight;i++)
{
for (int j=0;j<nScrrenWidth;j++)
{
BYTE dn1 = *pafScanblock1;
memcpy(szBuffer,(char*)(&dn1),1);
szBuffer += 1;
pafScanblock1 ++;
}
szBuffer = pTemp+dwBytes*i;
}
CPLFree(TempLock1);
BITMAPINFOHEADER bmiHdr;
BITMAPINFO MapInfo;
memset(&bmiHdr, 0, sizeof(BITMAPINFOHEADER));
bmiHdr.biBitCount = 3*8;
bmiHdr.biClrImportant = 0;
bmiHdr.biClrUsed = 0;
bmiHdr.biCompression = BI_RGB;
bmiHdr.biHeight = -nScrrenHeight;
bmiHdr.biPlanes = 1;
bmiHdr.biSize = sizeof(BITMAPINFOHEADER);
bmiHdr.biSizeImage = 0;
bmiHdr.biWidth = nScrrenWidth;
bmiHdr.biXPelsPerMeter = 0;
bmiHdr.biYPelsPerMeter = 0;
MapInfo.bmiHeader = bmiHdr;
MapInfo.bmiColors[0].rgbBlue = 0;
MapInfo.bmiColors[0].rgbGreen = 0;
MapInfo.bmiColors[0].rgbRed = 0;
MapInfo.bmiColors[0].rgbReserved = 0;
dc.SetStretchBltMode(MAXSTRETCHBLTMODE);
::StretchDIBits(dc.GetSafeHdc(), 0, 0, nScrrenWidth, nScrrenHeight,
0, 0, bmiHdr.biWidth, -bmiHdr.biHeight,
pTemp, (LPBITMAPINFO)(&MapInfo), DIB_RGB_COLORS, SRCCOPY);
GDALClose(poDataset);
delete []pTemp;
原文鏈接:tiff文件讀取
總結
以上是生活随笔為你收集整理的tiff或tif文件的读取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux内存查看及释放
- 下一篇: 支付宝加强非法买卖账户治理:有人卖账户赚