- - PR -
c# BitmapからBitmapへのコピー
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 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); | ||||||||
|
投稿日時: 2006-08-29 23:02
ダッチです。
私の環境( VS2005 C# )ではエラーは発生しませんでした。 このコードで確実に発生するのでしょうか? それと、ファイルをオープンするときは直接パスを指定するのではなく Stream を指定したほうがいいです。 Stream を指定しないと オープンしているときのファイルがロックされてしまいます。 例:
また Bitmap から Bitmap へのコピーとは離れるのですが、 結果としてファイルを複製しているように見えます。 それでしたら、下記のコードで済むと思います。
これだとだめなのでしょうか。 | ||||||||
|
投稿日時: 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は不可です。 | ||||||||
|
投稿日時: 2006-08-30 15:11
小さめのファイルでテストしたみたいだけど、その画像ファイルの大きさをちぢめてテストしたんだよね? 同じ形式でなければテストにならないよ。 | ||||||||
|
投稿日時: 2006-08-30 16:08
ぶさいくろうさん、ご指摘ありがとうございます。
元のBMPファイルを作成しているプログラムを変更し、横幅100画素程度の BMPで試しました。これだと正常に動作します。横幅7万だとやはりNGでした。 | ||||||||
|
投稿日時: 2006-08-30 17:13
DrawImage() は内部で Win32 API の BitBlt() を呼ぶのだと思いますが、BitBlt() に画像サイズの制限があった記憶があります。具体的なことは覚えていませんが、ビデオカードのデバイスドライバに依存してたかも。
大きな領域を一度で DrawImage() するのではなく、横方向とか縦方向とかで数回にわけて DrawImage() を呼んでみてはどうでしょうか。 |
1