C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: Byte配列のImageへの変換でエラー


(過去ログ 87 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■51895 / inTopicNo.1)  Byte配列のImageへの変換でエラー
  
□投稿者/ saw (1回)-(2010/07/25(Sun) 20:42:16)

分類:[C#] 

OS XP ProSP3
環境 VS2008 C#(.netFrameworkは2.0を使用)



いつも参考にさせてもらっています。

さっそくですが、どうしても解決できないことがあるので、質問をさせてください。

下記のサイトを参考に、Byteの配列になっているJpegの画像をImageへ変換し、
左右を反転させた後、再びByteの配列に戻すプログラムを作成しました。

Byte配列→Image、Image→Byte配列
http://www.atmarkit.co.jp/fdotnet/dotnettips/603byteimage/byteimage.html

左右の反転
http://dobon.net/vb/dotnet/graphics/rotateflip.html

ですが、Byte配列から、Imageへの変換の部分で、
「 GDI+ で汎用エラーが発生しました。」というエラーが発生することがあります。

Image img = (Image)imgconv.ConvertFrom(b);の部分です。

以下、調べてみた結果です。

出る画像は100%出ます。
Jpegのデータの確認は行いましたが、特に問題は無さそうでした。
出るデータと出ないデータの比較も行ってみましたが、一貫性は見受けられませんでした。
画像の容量なども、ファイルとなっているJpegのデータと比較してみましたが、同じです。
インターネットで調べ、処理を変えてみましたが、どれもうまくいかず、同様のエラーが発生しました。

・ストリームに読み込んでから、imageに変換
・一度、別の配列に移してから、変換
・DoEventsなどで一度、CPUに処理を返す。
・Sleepを入れる。

以上、お願いいたします。
引用返信 編集キー/
■51898 / inTopicNo.2)  Re[1]: Byte配列のImageへの変換でエラー
□投稿者/ Azulean (579回)-(2010/07/25(Sun) 23:46:17)
正直なところ、提示されている情報からは切り分けが難しいように思います。

たとえば、その 100% 失敗する画像ファイルを、Bitmap.FromFile メソッドで読み込むことはできるのでしょうか?
もし、できないのであれば、そのファイルが壊れているか、GDI+ では読み込めない画像になるかもしれません。
また、byte 配列に読み込む処理はどのような処理なのでしょうか?


これらの観点でも改善しない場合は、他の人も再現できるようなソースコード、サンプル画像など提示できないでしょうか?
引用返信 編集キー/
■51934 / inTopicNo.3)  Re[2]: Byte配列のImageへの変換でエラー
□投稿者/ saw (2回)-(2010/07/26(Mon) 21:45:42)
>Azuleanさん
回答ありがとうございます。

私もサンプルを出してしまうのが早いとは思っているのですが、その画像は人が映っていたりするため、公の場に航海することができません。
質問しておきながら、情報をこれ以上提供できないという、申し訳ない状況ですいません。

画像のファイルから、読み込んでと言う部分を確認するのが抜けていたので、確認を行ってみます。
引用返信 編集キー/
■51941 / inTopicNo.4)  Re[3]: Byte配列のImageへの変換でエラー
□投稿者/ すなふきぬ (20回)-(2010/07/27(Tue) 01:22:17)
2010/07/27(Tue) 01:26:21 編集(投稿者)
No51934 (saw さん) に返信
> >Azuleanさん
> 回答ありがとうございます。
> 
> 私もサンプルを出してしまうのが早いとは思っているのですが、その画像は人が映っていたりするため、公の場に航海することができません。
> 質問しておきながら、情報をこれ以上提供できないという、申し訳ない状況ですいません。
> 
> 画像のファイルから、読み込んでと言う部分を確認するのが抜けていたので、確認を行ってみます。

画像関係はGDI+で変換する場合はちょっと工夫が必要かもしれません。
画像の特定ができていないとのことですが、以前、似たような問題で悩んだので調べる部分を何点か。

・ImageのPixelFormatがFormat24bppRgbに変換できないような画像
 (gifなんかでパレットを指定している場合や圧縮方法が指定されている場合は同様のGDI+汎用エラーが出てたような気がします。)
・画像読み込みをFromStreamにする、Imageで読み込んで一旦Bitmapに変換する。
 (特定の画像のみで出るのなら、上記の方が濃厚な気がします)

.NETで画像を読み込む場合は、プロセスで掴んでしまう現象が発生するので、私はこんな感じで読み込みをしています。

using (FileStream fs = new FileStream(fname, FileMode.Open))
using (Image img = Image.FromStream(fs))
{
	Bitmap bmp = new Bitmap(img);
	bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution);
	return bmp;
}



私の場合は、機器から来るDIBデータをコードで変換していたので、DIBからBITMAPINFOHEADER、BITMAPFILEHEADERを算出して
生のBITMAP構造体を作成してから生成して切り抜けました。
BITMAP構造体のバイト配列からBitmapを生成するコードはこんな感じです。(ヘッダー部の生成を載せると結構な量になるので割愛します)


BITMAPINFOHEADER bih = new BITMAPINFOHEADER();
BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();

// (ヘッダ生成をごにょごにょ・・・)

// BITMAP形式のメモリ領域を作成する
byte[] bImage = new byte[bfh.bfSize];
fixed (void* pbfh = &bfh.bfType)
{
	Marshal.Copy((IntPtr)pbfh, bImage, 0, Marshal.SizeOf(bfh));
	Marshal.Copy(lpDib, bImage, Marshal.SizeOf(bfh), bih.biSize + bih.biSizeImage);
}

// BITMAPに変換後返却
ImageConverter iconv = new ImageConverter();
return (Bitmap)iconv.ConvertFrom(bImage);

読み込みの失敗するファイルがあれば調べることもできますが、公開できないようなのでちょっとずつ原因を切り分けていくしかないですね。

#長い文章があったので改行を挿入しました。

引用返信 編集キー/
■52199 / inTopicNo.5)  Re[4]: Byte配列のImageへの変換でエラー
□投稿者/ saw (3回)-(2010/08/03(Tue) 10:04:34)
>Azuleanさん
報告が遅くなってしまい申し訳ありません。
データをJpegのファイルとして落とし、確認してみました。
結果、XPでは表示すらできませんでした。(Paint等で読み込めない。)
ですが、VISTAでは一応、表示ができました。
一応、というのは、データの初め方の部分(画像の上の方)だけが表示され、
残りは灰色となって表示されてしまいました。
画像の大きさ等は認識できているようです。
どうも、画像データ自体がおかしいようなので、データの作成者に調査を依頼しています。

>すなふきぬさん
回答ありがとうございます。

> ・ImageのPixelFormatがFormat24bppRgbに変換できないような画像
>  (gifなんかでパレットを指定している場合や圧縮方法が指定されている場合は同様のGDI+汎用エラーが出てたような気がします。)
> ・画像読み込みをFromStreamにする、Imageで読み込んで一旦Bitmapに変換する。
>  (特定の画像のみで出るのなら、上記の方が濃厚な気がします)
画像のフォーマット等は一定(のはず)なので、ここは問題ないと考えています。

> .NETで画像を読み込む場合は、プロセスで掴んでしまう現象が発生するので、私はこんな感じで読み込みをしています。
>
> using (FileStream fs = new FileStream(fname, FileMode.Open))
> using (Image img = Image.FromStream(fs))
> {
> Bitmap bmp = new Bitmap(img);
> bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution);
> return bmp;
> }
私も今回の件を調べている過程で、同じような記事を見つけました。
今回は、Jpegの画像としてではなく、別の形でまとめられたデータを分解し、
その中の画像データを一度Byte配列のデータとして読み込んでいるので、ここも問題ないだろうと判断しました。


> 私の場合は、機器から来るDIBデータをコードで変換していたので、DIBからBITMAPINFOHEADER、BITMAPFILEHEADERを算出して
> 生のBITMAP構造体を作成してから生成して切り抜けました。
> BITMAP構造体のバイト配列からBitmapを生成するコードはこんな感じです。(ヘッダー部の生成を載せると結構な量になるので割愛します)
参考にさせて頂きます。
似たような方法を使って、コードでbyte配列をbmpに変換できる・・・?
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -