TIFF文件读取

以下是VC下读取TIFF文件的代码

//TIFFSetDirectory(tiff,0);//我们打开第一幅图,也就是第0帧,如果是第1帧,第二个参数写1,由此类推。因为Windows下图像基本//操作都是以BMP格式进行,我们读出该帧并转成BMP格式。
           char* szFileName = "test.tif";
	TIFF* tiff = TIFFOpen(szFileName, "r");	//打开Tiff文件,得到指针,以后所有的操作都通过指针进行

	int nTotalFrame = TIFFNumberOfDirectories(tiff);	//得到图像的总帧数

	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);


 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值