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

时间: 2024-11-08 21:01:40

tiff或tif文件的读取的相关文章

C# tif文件转jpg

需要添加WindowBase,PresentationCore的引用. 代码如下: private Stream GetImageStream() { //可以通过网络或本地文件的形式,返回Tif文件流 } Stream stream = GetImageStream() string fileName = "temp.jpg";//需要保存的文件名 using(FileStream fs = new FileStream(fileName,FileMode.Create) { Tif

JAI jar包转换tif文件报错解决办法,多页tif转多个jpeg方法

1. 定义文件枚举类 /**  * 文件类型枚举类  *  */ public enum FileType { /**       * JEPG.       */       JPEG("FFD8FF"),               /**       * PNG.       */      PNG("89504E47"),              /**       * GIF.       */       GIF("47494638"

vc中json文件的读取、修改和添加字段的方法

前言: 本代码涉及到对json文件的读取.修改和添加方法 WTL中radir button的状态判断和设置可选以及取消可选 示例: 所需头文件: #include <json.h> #include <file_io.h> 代码部分: //读取下载线路在界面上的radir button中显示 void CMainDlg::read_download_line_from_cfg() { std_string strDownloadLine; file_io<> json_

java使用POI实现excel文件的读取,兼容后缀名xls和xlsx

需要用的jar包如下: 如果是maven管理的项目,添加依赖如下: <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.14</version> </depen

考勤管理系统:实现数据在文件的读取功能

//获取系统时间的方法:Date date=new Date(new java.util.Date().getTime()); /* * 考勤管理系统:实现数据在文件的读取功能;两个模块,功能如下: * ----管理员模块: * 1.注册新用户 * 2.查询所用用户 * ----用户模块: * 1.上班打卡 * 2.下班打卡 * 3.查询历史打卡记录 * */public class TestUser { static Scanner input=new Scanner(System.in);

通过codehaus来实现json写入文件和读取文件成json对象

原文:通过codehaus来实现json写入文件和读取文件成json对象 代码下载地址:http://www.zuidaima.com/share/1550463256562688.htm pom.xml需要增加如下依赖: <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-lgpl</artifactId> <version>1.

Java数据存入文件和读取文件

在Java程序开发过程中我们发现并不能够让程序多次运行时获得上一次关闭程序前的运行结果--我们没有将运行的结果加以保存.这个时候我们就要找到Java操作读取数据的方法(以操作文件为例):Java中的输入/输出模型,I/O模型又称为I/O流.(以下简称I/O流). 流按方向可以分为输入(input)和输出(output)2种.输入和输出是相对的,这里我们是站在程序的角度来看的,将程序的数据写到文件就是输出,从文件中读取数据就是输入. 按类型(大小)可以分为字节型(byte)和字符型(byte)2种

c#用NPOI将excel文件内容读取到datatable数据表中

将excel文件内容读取到datatable数据表中,支持97-2003和2007两种版本的excel 1.第一种是根据excel文件路径读取excel并返回datatable 1 /// <summary> 2 /// 将excel文件内容读取到DataTable数据表中 3 /// </summary> 4 /// <param name="fileName">文件完整路径名</param> 5 /// <param name=

PHP 文件打开/读取

PHP Open File - fopen() 打开文件的更好的方法是通过 fopen() 函数.此函数为您提供比 readfile() 函数更多的选项. 在课程中,我们将使用文本文件 "webdictionary.txt": AJAX = Asynchronous JavaScript and XML CSS = Cascading Style Sheets HTML = Hyper Text Markup Language PHP = PHP Hypertext Preproces