1

当我通过 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 图像查看器中正确显示。只是翻转数据顺序更安全吗?

4

1 回答 1

0

Windows 位图与底线一起存储。基本上他们使用笛卡尔坐标系,将点(0,0)放在左下角。

因此,您可能应该只调整for编写扫描线的代码中的循环(使其以相反的顺序编写扫描线)。

使用TiffTag.ORIENTATION标签也是一种解决方案,但问题是:大多数观众完全忽略了这个标签。

于 2012-11-09T15:41:37.190 回答