23

ディスクから PNG 画像をロードする C#/.NET ユーティリティを作成しました。

Bitmap b = Bitmap.FromStream(new MemoryStream(File.ReadAllBytes(filename))) as Bitmap;

それらに対していくつかの変換(回転、スケーリング、アルファ)を​​実行し、適用された変換に基づいて異なるファイル名で結果のPNG画像をディスクに保存します

b.Save(outputName, ImageFormat.Png);

このユーティリティを使用して、何千もの PNG の書き込みに成功しました。ただし、libpng を使用する別のプログラムで、PNG の 1 つが読み込まれないことがあります。そのプログラムでは、libpng で「IDAT が多すぎます」というエラーが表示されます。

PNG ファイルを調べると、ファイルの最後で IEND チャンクの直前に「不正な」IDAT チャンクがあることがわかります。そのような IDAT チャンクの 1 つ (および次の IEND チャンク) は、16 進エディターで次のように表示されます。これらは、ファイルの最後の 24 バイトです。

IDAT: 0x00 0x00 0xFF 0xF4 0x49 0x44 0x41 0x54 0x35 0xAF 0x06 0x1E    
IEND: 0x00 0x00 0x00 0x00 0x49 0x45 0x4e 0x44 0xAE 0x42 0x60 0x82

IDAT チャンクの長さは 0xFFF4 として表示されます。ただし、明らかなように、IDAT チャンク (さらに言えばファイル) にはそれほど多くのバイトはありません。

他の誰かがこの問題に遭遇しましたか? いくつかの方法のいずれかで問題を解決できます。PNG ファイルを手作業で編集して、最後の IDAT チャンクを削除する (またはサイズを 0 に設定する) ことができます。破損した PNG を修正する 2 次プログラムを実行できます。ただし、元のプログラムに簡単に追加できる C#/.NET ソリューションが必要です。理想的には、PNG をバイナリ ファイルとして再度開く必要のないソリューションが必要です。不正な IDAT チャンクをチェックします。PNGを書き直します。しかし、私はそれが私がする必要があることだと考え始めています.

4

2 に答える 2

0

画像を再現できないため、これは実際には完全な答えではありません。ただし、別のBitmapコンストラクターを使用して画像を読み込んでみることができます。

http://msdn.microsoft.com/en-us/library/0cbhe98f.aspx

コードを次のように変更します。

Bitmap b = new Bitmap(filename);

そのコンストラクターは、生のバイトを読み取る代わりに、いくつかのネイティブ GDI+ 関数を使用してイメージをメモリにロードするためです。

http://dotnetframework.org/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/CommonUI/System/Drawing/Bitmap@cs/1305376/Bitmap@cs

イメージをディスクに書き込むときに問題があるように見えますが、違いがある可能性があります。

于 2013-10-25T00:10:03.033 に答える