- PR -

c# BitmapからBitmapへのコピー

1
投稿者投稿内容
MASA
会議室デビュー日: 2006/08/15
投稿数: 4
投稿日時: 2006-08-29 21:02
c# BitmapからBitmapへのコピー

BitmapからBitmapへのコピーをするために、DrawImageを使ってみたのですが
bitmap2.Saveのラインで
「'System.ArgumentException' のハンドルされていない例外が system.drawing.dll で発生しました。
 追加情報 : 使用されたパラメータが無効です。」
というエラーが出てしまいます。

c:\test.bmpはフルカラーの画像ですが、bitmap2の属性に誤りがあるのか、DrawImageの使い方が悪いのか、
分かりません。

なぜ、bitmap2.Saveでエラーが出るのかを含めて、アドバイスいただければ助かります。


Bitmap bitmap1 = new Bitmap(@"c:\test.bmp");
Bitmap bitmap2 = new Bitmap(bitmap1.Width, bitmap1.Height,PixelFormat.Format32bppArgb);

Graphics graphics2 = Graphics.FromImage(bitmap2);

graphics2.DrawImage(bitmap1, 0, 0);

bitmap2.Save(@"c:\test_out.bmp", ImageFormat.Bmp);

ダッチ
大ベテラン
会議室デビュー日: 2005/10/31
投稿数: 113
投稿日時: 2006-08-29 23:02
ダッチです。

私の環境( VS2005 C# )ではエラーは発生しませんでした。
このコードで確実に発生するのでしょうか?

それと、ファイルをオープンするときは直接パスを指定するのではなく
Stream を指定したほうがいいです。
Stream を指定しないと オープンしているときのファイルがロックされてしまいます。

例:
コード:
System.IO.FileStream stream = new System.IO.FileStream(@"g:\\test1.bmp", System.IO.FileMode.Open);
            Bitmap bitmap1 = new Bitmap(stream);



また Bitmap から Bitmap へのコピーとは離れるのですが、
結果としてファイルを複製しているように見えます。
それでしたら、下記のコードで済むと思います。

コード:
System.IO.File.Copy("@c:\\test.bmp", @"c:\\test_out.bmp");


これだとだめなのでしょうか。
MASA
会議室デビュー日: 2006/08/15
投稿数: 4
投稿日時: 2006-08-30 14:40
ダッチさん、レスポンスありがとうございます。

私の環境は、VS2003 C#です。ダッチさんの「エラーは発生しません」の情報を基に
入力BMPを「普通サイズの画像」にしたら、正常に動きました。

ただ、私が動かそうとしているのは横約7万画素の巨大な画像です。エラーには、おそらく
これが関係していると思われます。

ちなみに
graphics2.DrawImage(bitmap1, 0, 0);


for(int i=0; i<bitmap1.Width; i++)
for(int j=0; j<bitmap1.Height; j++)
bitmap2.SetPixel(i, j, bitmap1.GetPixel(i,j));

と置き換えると、横約7万画素の巨大な画像でも動作します。
(ただし、処理時間がかかり、アンセーフモードで書き直す必要がありそうですが。)

DrowImageを実行するとき、ユーザから見えないワークエリアが取られ、それが巨大画像との
関係で、エラーを誘発している可能性がありますね。


追伸
 ダッチさんご指導の「Stream指定」、初めて知りました。ファイルロック回避のための
属性指定があるはずと、探していたので、助かりました。
 また、System.IO.File.Copyの件ですが、処理の概要は、BMP画像を読み込み、その画像の下部に
余白をつくり、加工した後、再度ファイルに書き出すもので、そのため読み込みに使うBitmap から
サイズの違う書き込み用Bitmapに、画像をコピーしたいことなので、System.IO.File.Copyは不可です。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-08-30 15:11
引用:

MASAさんの書き込み (2006-08-30 14:40) より:
ただ、私が動かそうとしているのは横約7万画素の巨大な画像です。エラーには、おそらく
これが関係していると思われます。


小さめのファイルでテストしたみたいだけど、その画像ファイルの大きさをちぢめてテストしたんだよね?
同じ形式でなければテストにならないよ。
MASA
会議室デビュー日: 2006/08/15
投稿数: 4
投稿日時: 2006-08-30 16:08
ぶさいくろうさん、ご指摘ありがとうございます。
元のBMPファイルを作成しているプログラムを変更し、横幅100画素程度の
BMPで試しました。これだと正常に動作します。横幅7万だとやはりNGでした。
スフレ
ぬし
会議室デビュー日: 2005/05/27
投稿数: 281
お住まい・勤務地: 東京
投稿日時: 2006-08-30 17:13
DrawImage() は内部で Win32 API の BitBlt() を呼ぶのだと思いますが、BitBlt() に画像サイズの制限があった記憶があります。具体的なことは覚えていませんが、ビデオカードのデバイスドライバに依存してたかも。

大きな領域を一度で DrawImage() するのではなく、横方向とか縦方向とかで数回にわけて DrawImage() を呼んでみてはどうでしょうか。
1

スキルアップ/キャリアアップ(JOB@IT)