3

タイプ6OJPEGで圧縮されたTIFF画像に出くわしました。その多くは、「8 8 8」の同じBitsPerSampleを持ち、正常に動作します。

ただし、BitsPerSampleの値が「8256080」であるものが時々見られます。これが可能かどうか、そうでない場合は、TIFFを生成したシステムのバグかどうか疑問に思います。もしそうなら、BitsPerSampleが "8 8 8"になるようにタグを変更するだけで修正できる可能性がありますか?

現在、非圧縮TIFFに変換して処理できるツール(LEAD)は1つしか見つかりませんでした。明らかに、これがどのように行われるのかわかりません。非常に少数の画像の問題を解決するためだけに大きなオーバーヘッドが発生します。

誰かがこれに出くわしたり、これを修正するのが簡単か複雑かについて私よりも多くの知識を持っていますか?これまでのところ、Libtiff.netコードをいじくり回そうとした私の試みはあまり実りませんでした!

乾杯

更新:litiff.netを次のような単純なもので使用する:

    static void Main(string[] args)
    {
        using (Tiff image = Tiff.Open(args[0], "r"))
        {
            FieldValue[] value = image.GetField(TiffTag.IMAGEWIDTH);
            int width = value[0].ToInt();

            Console.WriteLine(string.Format("Width = {0}", width));
        }
    }

結果は(明らかに例外処理をスキップしました!):

ReadDirectory:警告、10.TIF:タグ33000(0x80e8)の不明なフィールドが検出されました10.TIF:フィールド「BitsPerSample」の異なるサンプルごとの値を処理できません

未処理の例外:System.NullReferenceException:オブジェクト参照がオブジェクトのインスタンスに設定されていません。C:\ tiffstuff \ tifftest \ tifftest \ Program.cs:line15のtifftest.Program.Main(String [] args)でセグメンテーション違反

チェックをバイパスして「BitsPerSample」を8と想定していますが、ビットミラクルサイトの例を使用して、画像を抽出してBMPとして保存しようとしています。

            using (Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb))
            {
                Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

                BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                byte[] bits = new byte[bmpdata.Stride * bmpdata.Height];

                for (int y = 0; y < bmp.Height; y++)
                {
                    int rasterOffset = y * bmp.Width;
                    int bitsOffset = (bmp.Height - y - 1) * bmpdata.Stride;

                    for (int x = 0; x < bmp.Width; x++)
                    {
                        int rgba = raster[rasterOffset++];
                        bits[bitsOffset++] = (byte)((rgba >> 16) & 0xff);
                        bits[bitsOffset++] = (byte)((rgba >> 8) & 0xff);
                        bits[bitsOffset++] = (byte)(rgba & 0xff);
                    }
                }

                System.Runtime.InteropServices.Marshal.Copy(bits, 0, bmpdata.Scan0, bits.Length);
                bmp.UnlockBits(bmpdata);

                bmp.Save("c:\\tiffstuff\\TiffTo24BitBitmap.bmp");
            }

明らかにOJPEG警告が表示され、次に次のように表示されます。OJPEGReadHeaderInfoSecTablesQTable:JPEGテーブルがありません

結果の画像は100%緑色です。

これを修正するという点で、私は自分の深さから離れすぎていますか?私はJPEGがどこかにあることを知っていますが、JPEGを取得して正常に解凍できないようです:-(

4

2 に答える 2

1

25608のビット深度は間違いなく間違っています。JPEG圧縮では、ピクセルあたり8ビット以外のビット深度は使用されません。ピクセルあたり16ビットまたは32ビットを使用できる他の画像形式もありますが、これは通常のアプリケーションと同じくらい高いものです。

JPEGには、RGB画像(「8 8 8」)、CMYK画像(「8 8 8 8」)、およびモノクロ画像(つまり)があります。「8」。

画像がCMYKであり、使用しているソフトウェアがそれをサポートしていない可能性があります。その場合、そのソフトウェアで使用するには、RGBに変換する必要があります。

画像がRGBの場合、タグは単に破損しているため、修正すると画像は正常に機能します。(もちろん、他に破損しているものはないと仮定します。)

于 2013-02-06T13:21:57.257 に答える
1

ファイルが半分壊れているようです。@Guffaが述べたように、OJPEGファイルの場合、サンプルあたりのビット数は8 8 8(RGB)または8 8 8 8(CMYK)である必要があります

残念ながら、LibTiff.Net は のような重要なタグを修復する機会を与えませんBITSPERSAMPLE

私が見る唯一のオプションは、そのようなファイルの自動修正コードをライブラリに追加することです。

エラーを発生させるコードはTiff_DirRead.csファイルにあります (以下に示す 3 つの場所)。

private bool fetchPerSampleShorts(TiffDirEntry dir, out short pl)
{
    ...
    for (ushort i = 1; i < check_count; i++)
    {
        if (v[i] != v[0])
        {
            ErrorExt(this, m_clientdata, m_name,
                "Cannot handle different per-sample values for field \"{0}\"",
                FieldWithTag(dir.tdir_tag).Name);
            failed = true;
            break;
        }
    }
    ...
}

private bool fetchPerSampleLongs(TiffDirEntry dir, out int pl)
{
    ...
    for (ushort i = 1; i < check_count; i++)
    {
        if (v[i] != v[0])
        {
            ErrorExt(this, m_clientdata, m_name,
                "Cannot handle different per-sample values for field \"{0}\"",
                FieldWithTag(dir.tdir_tag).Name);
            failed = true;
            break;
        }
    }
    ...
}

private bool fetchPerSampleAnys(TiffDirEntry dir, out double pl)
{
    ...
    for (ushort i = 1; i < check_count; i++)
    {
        if (v[i] != v[0])
        {
            ErrorExt(this, m_clientdata, m_name,
                "Cannot handle different per-sample values for field \"{0}\"",
                FieldWithTag(dir.tdir_tag).Name);
            failed = true;
            break;
        }
    }
    ...
}

if (v[i] != v[0])句と対応するエラー処理コードを削除しようとする場合があります。これでファイルを開くことができると思います(他に問題がない場合)。

そのようなファイルを何らかの形で変換するか、少なくともパッチを当てたいと思うかもしれません。

于 2013-02-06T16:19:16.333 に答える