Board logo

标题: 用 libtiff 进行图形编程-1 [打印本页]

作者: look_w    时间: 2018-4-16 13:14     标题: 用 libtiff 进行图形编程-1

TIFF(标记图像文件格式(Tag Image File Format))是一种最初由 Adobe 提出的光栅图像格式。 光栅图像格式将图片存储为描述像素状态的位图,而不是记录图元(譬如,线和曲线)的长度和位置。Libtiff 是 TIFF 规范的标准实现之一,目前它因其速度、强大的功能和源代码的易于获取而被广泛使用。
本文专注于黑白 TIFF 图像;以后可能会有文章讨论彩色图像。
TIFF 挑战大多数文件格式规范定义文件表示的一些基本规则。 例如,PNG 文档(TIFF 的一个竞争者)始终使用大尾数法。然而,TIFF 没有这种规定。下面的示例列出了某些看起来很基本而 TIFF 并未定义的内容:
创建 TIFF 文件很容易,因为几乎不需要对您已有的数据进行任何转换。 另一方面,它也意味着读入其它应用程序创建的随机 TIFF 会很困难 ― 所以您必须编码所有可能的组合,以确信得到可靠的产品。
那么,如何编写一个应用程序来读入 TIFF 格式的所有可能的不同排列呢? 最重要的是要记住        决不要假设正在读入的图像数据的格式。
写 TIFF 文件首先,我将向您演示如何写出 TIFF 文件。然后,我将演示如何将 TIFF 文件读回程序中。
写操作的基础设施传统上, 位图在代码内由一个字符数组表示。这是因为在大多数操作系统上,一个字符能很好地映射成一个字节。 在清单 1 中,我设置了 libtiff 并创建一个简单的缓冲区,使之包含我稍后可以写到磁盘上的图像。 您可以下载该代码,作为 write-infrastructure.c(请参阅本文后面的 )。      
清单 1. 设置基础设施(write-infrastructure.c)
1
2
3
4
5
6
7
#include <stdio.h>
#include <tiffio.h>
int
main (int argc, char *argv[])
{
  char buffer[32 * 9];
}




上面的代码相当简单。要使用 libtiff,只需要包含 tiffio.h 头文件。要编译它, 请使用命令         gcc foo.c -o foo -ltiff -lm 。         -ltiff 是包含名为 libtiff 的库的命令,该库必需在库路径中。一旦开始显式地指定库, 还必需添加         -lm ,它是数学库。这里定义的 char buffer 将是黑白图像, 所以我们接下来定义其中的一个。      
写图像为了凑足那个令人生厌的示例, 我现在很乐意向您提供迄今为止可能是画得最差的悉尼港大桥的图片。在清单 2 中,图像已经在图像缓冲区中,我们只需将它保存到磁盘上的文件中。 该示例先以写方式打开一个 TIFF 图像,然后将该图像放到该文件中。
请注意,为了清晰起见,我省略了该图像的实际十六进制值;如果对它们感兴趣, 可以从这段代码的可下载版本 write.c(请参阅 )中获得它们。      
清单 2. 写操作的代码(write.c)
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
#include <stdio.h>
#include <tiffio.h>
int main(int argc, char *argv[]){
  // Define an image
  char buffer[25 * 144] = { /* boring hex omitted */ };
  TIFF *image;
  // Open the TIFF file
  if((image = TIFFOpen("output.tif", "w")) == NULL){
    printf("Could not open output.tif for writing\n");
    exit(42);
  }
  // We need to set some values for basic tags before we can add any data
  TIFFSetField(image, TIFFTAG_IMAGEWIDTH, 25 * 8);
  TIFFSetField(image, TIFFTAG_IMAGELENGTH, 144);
  TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 1);
  TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, 1);
  TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 144);
  TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
  TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
  TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
  TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  TIFFSetField(image, TIFFTAG_XRESOLUTION, 150.0);
  TIFFSetField(image, TIFFTAG_YRESOLUTION, 150.0);
  TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
   
  // Write the information to the file
  TIFFWriteEncodedStrip(image, 0, buffer, 25 * 144);
  // Close the file
  TIFFClose(image);
}




(在我的 Linux 机器上使用         xview 命令将不能显示输出图像。事实上, 我还没发现哪一个以 group 4 fax 方式压缩的黑白图像可以使用那个程序显示出来。 在发表本文时,我仍无法找到这个程序的修正。)      
无论如何,样本代码演示了使用 libtiff API 的基本要素。值得注意的几点是:
如果您对悉尼港大桥的外观感到好奇,可以看一下 ,它是该图片的副本。 (我不得不作弊并将它转换成 JPEG,因为大多数 Web 浏览器不支持 TIFF。)      
有关 libtiff 函数调用的更多信息如果您需要有关本文中提到的任何 libtiff 函数调用的更多信息,请参阅与该库一起提供的详尽的帮助页。
         请记住,帮助手册页面中的大小写很重要,所以需要正确拼写函数名中的字母大小写。 例如,它是           TIFFOpen ,而不是           tiffopen 。        

图 1. Michael Still 绘制的悉尼港大桥




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0