转自: https://www.cnblogs.com/chaos77/p/6740242.html
最近的一个项目用到tif图片格式读写。tif是一种图像文件格式,最初用于黑白传真,后来也支持彩色。相对于其他图像格式,tif有点像容器,支持多页不同尺寸、不同的压缩格式。黑白的压缩算法常见为CCITT 4/6,无损压缩,不支持灰度和彩色;彩色的常见压缩算法为LZW无损压缩,对文字和矢量图形的效果不错,但对于照片的压缩率很差。最新的tif格式也支持jpeg有损压缩和zip压缩,不过很多旧版软件不支持,如XP图片查看器等。
最初为了图方便,我使用了windows自带的gdi+来读写tif,但后来发现几个无法解决的问题
1.在32位系统上,打开2G以上的tif文件失败;
2.被某些应用(如splwow64)调用时,总是失败;
无奈之下只好换方案,使用libtiff库。本来想下载编译好的dll文件,不过都没64位的,干脆自己编一下吧。
【编译】
libtiff引用了jpeg,zip库,一开始我用不着这两个,就把他们去掉了:
1.libtiff\makefile.vc 注释tif_jpeg/pixarlog/zip三行
2.tiffconf.h 注释 JPEG_SUPPORT,PIXARLOG,ZIP三行
编译64位版本是我用了VS2008 x64 win64 command prompt tools,运行 nmake /f makefile.vc 但编译出来的dll依赖mfc90.dll等文件,最好改为静态链接: nmake.opt OPTFLAGS, MD->MT 另外可以不生成pdb: nmake.opt- LD=link /nologo 加上 /pdb:none
32位也可以用VC6编译:VC6\VC98\Bin\VCVARS32.bat 命令同上
编译生成libtiff.dll, libtif_i.lib(dynamic), libtiff.lib(static) 不过我还是建了一个VC工程来编译,更方便一些。 ==========================================================
如果要支持jpeg编码,请到http://www.ijg.org/ 下载源码包jpegsrxc
copy jconfig.vc jconfig.h ; nmake /f makefile.vc libjpeg.lib ; 默认生成libjpeg.lib静态库 在libtiff\makefile.vc,tiffconf.h开启jpeg行,nmake.opt中打开jpeg项目并写入路径 64位编译时,要在makefile.vc CFLAGS=..加上/Ox /MT /GX /W3 静态链接MFC.
==========================================================
用VC编译应用程序没问题,但在WDK编译驱动时遇到错误[unresolved external symbol __imp__TIFFOpen@4 referenced].这里TIFFOpen后面为什么有个@4?看了下Lib文件里有这些函数但没有@序号。这是因为libtiff都是c函数,默认是cdecl调用方式,dll输出函数不带@序号。而WDK编译驱动时默认是stdcall(/Gz)编译方式,链接时就找不到了。这里需要把libtiff里的函数都加上__stdcall修饰再重编译,不过改动比较多,也可以加上/Gz编译选项,或在VC的Code Generation/Advanced - calling convention 选为stdcall(/Gz)编译,注意libjpeg也要重新编译。如果以stdcall编译后,头文件tiffio.h中的函数也必须加上__stdcall修饰。
【使用】
1 2 3 4 5 6 7 8 9 10 11 |
|
错误和警告信息
libtiff使用CallBack方式显示错误和警告。定义如下函数
1 2 3 4 5 6 |
|
Directories 多页
一个tif文件可以包含多页,每页的宽高大小都可以不同,在libtiff中称为Directories.
获取页数 npage = TIFFNumberOfDirectories(TIFF*);
跳到指定页数 TIFFSetDirectory(TIFF*, tdir_t);
写入一页 TIFFWriteDirectory(TIFF*);
tif图像的三种压缩和组织形式scanline,strip,tile
scanline:每行图像压缩,只支持ccitt等算法,不支持lzw,jpeg等
strip:图像分为几个横条压缩,
tile: 图像分为若干个正方形块进行压缩
与其他图像格式转换的问题
彩色tif内的颜色顺序为rgb,在bmp内的顺序为bgr,两者需要翻转
黑白tif可调用TIFFSetField(pTif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK/WHITE)来指定0-1为黑、白,不过有些软件不支持。
tif内的每行数据为1字节对齐,bmp为4字节对齐 使用jpeg算法压缩时,strip的高度必须为8的倍数
最后附上tif-bmp转换的代码例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
|