tiff檔案讀取
轉自:http://blog.csdn.net/zhouxuguang236/article/details/7846615
以下是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;
相關文章
- 任意檔案讀取
- Java 讀取檔案Java
- go配置檔案讀取Go
- python讀取大檔案Python
- springboot讀取配置檔案Spring Boot
- 用友任意檔案讀取
- viper 讀取配置檔案
- matlab讀取npy檔案Matlab
- python小白檔案讀取Python
- cocos讀取plist檔案
- python 讀取文字檔案Python
- IOC - 讀取配置檔案
- 前端讀取excel檔案前端Excel
- 讀取檔案流並寫入檔案流
- Springboot整合MongoDB儲存檔案、讀取檔案Spring BootMongoDB
- java中讀取配置檔案Java
- go–讀取檔案的方式Go
- C#讀取Xml檔案C#XML
- pg從磁碟讀取檔案
- Spring之Property檔案讀取Spring
- 01 讀取模板HTML檔案HTML
- go 讀取.ini配置檔案Go
- 6.1檔案下載、讀取
- 讀取資料夾檔案
- Mysql溯源-任意檔案讀取?MySql
- Java系列:讀取XML檔案JavaXML
- python如何讀取大檔案Python
- MATLAB快速讀取STL檔案Matlab
- 使用pillow開啟TIFF檔案報tempfile.tif: Cannot read TIFF header錯誤的解決方案Header
- Golang專案中讀取配置檔案Golang
- C#讀取文字檔案和寫文字檔案C#
- spark直接讀取本地檔案系統的檔案Spark
- mybatis讀取properties檔案內容MyBatis
- Android讀取配置檔案的方法Android
- 使用yaml檔案讀取資料YAML
- Python 讀取HDF5檔案Python
- Vmware Vcenter 任意檔案讀取漏洞
- Rust 程式設計,讀取檔案Rust程式設計
- Nuxt3讀取markdown檔案UX