当我通过libtiff.net处理来自扫描仪的图像时,我正在观察“镜像”效果。
这是我的代码:
public static byte[] GetTiffImageBytes(byte[] win32Bitmap, WinApi.BITMAPINFOHEADER infoHeader)
{
try
{
using (var ms = new MemoryStream())
{
using (Tiff tif = Tiff.ClientOpen("InMemory", "w", ms, new TiffStream()))
{
if (tif == null)
return null;
tif.SetField(TiffTag.IMAGEWIDTH, infoHeader.biWidth);
tif.SetField(TiffTag.IMAGELENGTH, infoHeader.biHeight);
tif.SetField(TiffTag.COMPRESSION, Compression.CCITTFAX4);
tif.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
tif.SetField(TiffTag.ROWSPERSTRIP, infoHeader.biHeight);
// TODO: ? Used to be resolutions?
tif.SetField(TiffTag.XRESOLUTION, infoHeader.biWidth);
tif.SetField(TiffTag.YRESOLUTION, infoHeader.biHeight);
tif.SetField(TiffTag.SUBFILETYPE, 0);
tif.SetField(TiffTag.BITSPERSAMPLE, 1);
tif.SetField(TiffTag.FILLORDER, FillOrder.MSB2LSB);
tif.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);
tif.SetField(TiffTag.SAMPLESPERPIXEL, 1);
tif.SetField(TiffTag.T6OPTIONS, 0);
tif.SetField(TiffTag.RESOLUTIONUNIT, ResUnit.INCH);
tif.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
// Image "stride" is a lenght in bytes of one pixel row
var stride = infoHeader.biSizeImage / infoHeader.biHeight;
var offset = infoHeader.biSize;
// raster stride MAY be bigger than TIFF stride (due to padding in raster bits)
for (int i = 0; i < infoHeader.biHeight; i++)
{
var res = tif.WriteScanline(win32Bitmap, offset, i, 1);
if (!res) return null;
offset += stride;
}
}
return ms.GetBuffer();
}
}
catch (Exception ex)
{
return null;
}
}
我根据以下示例调整了此代码:http://bitmiracle.com/libtiff/help/convert-system.drawing.bitmap-to-a-black-and-white-tiff.aspx
传入的win32位图有标题(也作为参数重复)。 基本上,我将数据行复制到TIFF中,我确实获得了图像,但它是镜像的,如下所示: 我是win32代码的新手(这个位图来自twain驱动程序)并且不确定它是否与操作系统有关。
我通过Silvrlight的P-Invoke调用win32,我得到了位图,并在Silverlight的LibTiff.net版本中处理。当我将它们添加到TIFF时,我想我需要“镜像”扫描线但是我想知道我是否需要重新发明轮子或它已经以某种方式包含在库中了?
当我使用上面的代码处理图像时,看看图像是如何出现的:
修改
更改了以下行:
tif.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);
所以它说BOTTOMLEFT并且它为我的应用程序修复了它。当我使用LibTiff读取和显示数据时,它可以工作。但!它无法在Windows图像查看器中正确显示。只是翻转数据顺序更安全吗?
答案 0 :(得分:0)
Windows位图首先存储在底线。基本上他们使用笛卡尔坐标系,它将点(0,0)放在左下角。
因此,您可能应该在编写扫描线的代码中调整for
循环(使其以相反的顺序写入扫描线)。
使用TiffTag.ORIENTATION
标记也是一种解决方案,但问题是:大多数观看者完全忽略此标记。