我有一个程序可以获取图像并将其写入TIFF文件。图像可以是灰度(8位),灰度,带alpha通道(16位),RGB(24位)或ARGB(32位)。在没有alpha通道的情况下写出图像没有任何问题,但是对于带有alpha的图像,当我尝试设置额外的samples标签时,我会被发送到由TIFFSetErrorHandler设置的TIFF错误处理例程。传入的消息是_TIFFVSetField模块中的<filename>: Bad value 1 for "ExtraSamples"
。下面是一些示例代码:
#include "tiff.h"
#include "tiffio.h"
#include "xtiffio.h"
//Other includes
class MyTIFFWriter
{
public:
MyTIFFWriter(void);
~MyTIFFWriter(void);
bool writeFile(MyImage* outputImage);
bool openFile(std::string filename);
void closeFile();
private:
TIFF* m_tif;
};
//...
bool MyTIFFWriter::writeFile(MyImage* outputImage)
{
// check that we have data and that the tiff is ready for writing
if (outputImage->getHeight() == 0 || outputImage->getWidth() == 0 || !m_tif)
return false;
TIFFSetField(m_tif, TIFFTAG_IMAGEWIDTH, outputImage->getWidth());
TIFFSetField(m_tif, TIFFTAG_IMAGELENGTH, outputImage->getHeight());
TIFFSetField(m_tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField(m_tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
if (outputImage->getColourMode() == MyImage::ARGB)
{
TIFFSetField(m_tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(m_tif, TIFFTAG_BITSPERSAMPLE, outputImage->getBitDepth() / 4);
TIFFSetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, 4);
TIFFSetField(m_tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_ASSOCALPHA); //problem exists here
} else if (/*other mode*/)
//apply other mode settings
//...
return (TIFFWriteEncodedStrip(m_tif, 0, outputImage->getImgDataAsCharPtr(),
outputImage->getWidth() * outputImage->getHeight() *
(outputImage->getBitDepth() / 8)) != -1);
}
据我所见,标签永远不会写入文件。幸运的是,GIMP仍然认识到额外的频道是alpha,但其他一些需要阅读这些TIFF的节目并不那么慷慨。我缺少必须在TIFFTAG_EXTRASAMPLES之前设置的标签吗?我错过了其他需要的标签吗?任何帮助将不胜感激。
答案 0 :(得分:4)
我找到了解决方案。 Extra_Samples字段不是uint16,而是首先是一个count(即uint16),然后是该大小的数组(类型为uint16)。因此呼叫应如下所示:
uint16 out[1];
out[0] = EXTRASAMPLE_ASSOCALPHA;
TIFFSetField( outImage, TIFFTAG_EXTRASAMPLES, 1, &out );
原因是允许多个额外样本。
希望这有帮助!
干杯, 卡斯帕
答案 1 :(得分:2)
感谢 Kaspar、Tomas 和其他所有人的宝贵指导。
以下是该线程中 RGBA 的相关位:
const uint16 extras[] = {EXTRASAMPLE_ASSOCALPHA};
TIFFSetField(tifptr, TIFFTAG_SAMPLESPERPIXEL, 4);
TIFFSetField(tifptr, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(tifptr, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_ASSOCALPHA, 1, extras);
其中 tifptr 是指向 tiffio.h
中定义的 TIFF 类型的指针。
这是帮助消除 TIFF 标签歧义的链接:
https://www.awaresystems.be/imaging/tiff/tifftags/extrasamples.html
这是获取 libtiff 源代码的链接:
谢谢!
关于 va_list 和朋友的注意事项:
当使用 va_list(可变参数列表)和朋友,并且提供的参数数量不正确时,您会得到无用的段错误。对我来说,这里的教训是,如果您使用的是现代 C 库,并且遇到了无用的段错误,您至少应该考虑这是因为您将长度而不是数组传递给 va 宏。