• 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文件读取

  • 相关阅读:
    Hadoop跳过回收站删除HDFS文件
    hadoop安全模式解除方法和为什么会安全模式
    从业18年,我总结了9个最有价值的经验
    mysql复制整个数据库及数据
    Oozie调度原理(queueName与launcher_queName详解)
    Hive升级参考
    Hive表设计压缩问题
    sql中join的on和where操作引发的谓词下推优化
    将毫秒转换成天小时分钟
    数据库优化之一:通过修改postgresql的Planner Method Configuration更改 查询计划优化慢sql
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/5461464.html
Copyright © 2020-2023  润新知