DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ビットマップをbyte配列にしたときにエラー(LockBits Marshal.Copy)

環境/言語:[VB2005]
分類:[.NET]

下記ソース(VB2005)で
800×600ピクセルのビットマップだと正しく処理されますが、
1000×1000ピクセルのビットマップだと下のようなエラーが発生します。

System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)の場所で
「保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。」

環境なのか?コードの問題なのか不明です。(ちなみにC#でも同じでした。)
お教えください。

Dim srcBmp As New Bitmap("C:\800600.jpg")
'Dim srcBmp As New Bitmap("C:\10001000.jpg")

Dim rect As New Rectangle(0, 0, srcBmp.Width, srcBmp.Height)

Dim bmpData As System.Drawing.Imaging.BitmapData = srcBmp.LockBits(rect, ImageLockMode.ReadWrite, srcBmp.PixelFormat)

Dim ptr As IntPtr = bmpData.Scan0

Dim bytes As Integer = srcBmp.Width * srcBmp.Height * 3
Dim rgbValues(bytes - 1) As Byte

System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)

Dim counter As Integer
For counter = 1 To rgbValues.Length - 2 Step 3
rgbValues(counter) = 255
Next

System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)

srcBmp.UnlockBits(bmpData)

Dim g As Graphics = Me.CreateGraphics()
g.DrawImage(srcBmp, 5, srcBmp.Height + 10, srcBmp.Width, srcBmp.Height)
g.Dispose()
とりあえず気になった点を…
> Dim bytes As Integer = srcBmp.Width * srcBmp.Height * 3
> Dim rgbValues(bytes - 1) As Byte
bytesの値を<srcBmp.Width*3を4の倍数に切り上げた値>*srcBmp.Heightとしてみてください
とりあえず気になった点を…便乗して
Marshal.Copy(ptr, rgbValues, 0, bytes)
Marshal.Copy(rgbValues, 0, ptr, bytes)
何か、変な気がするのですが (調べてません。正しいのなら、無視してくださ〜い)
> bytesの値を<srcBmp.Width*3を4の倍数に切り上げた値>*srcBmp.Heightとしてみてください
むしろ BitmapData.Stride を使うべきですね(負数の可能性に注意)。高さも BitmapData.Height の方を使った方が自然。
1000 ピクセルなら 4 バイト境界は関係なさそうですが。

// Jpeg がソースなら 24bpp 決め撃ちでも問題なさそうだけど……。
申し訳ありません。自己解決です。

間違いがありました。確認ファイルがbmp形式でした。

最初、800×600はjpgとbmpで両方できていたので、
確認したのが、10001000はbmpファイルでした。
それでエラーになっていました。

10001000.jpgでは正常に変換表示できました。

お騒がせしました。本当に申し訳ありませんでした。

もさん、y4yamaさん、Hongliangさん返信ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板