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ドライバーからのもの)は非常に新しく、OSに関連しているかどうかはわかりません。

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 に答える