使用LockBits时AccessViolation

编程入门 行业动态 更新时间:2024-10-27 01:29:52
本文介绍了使用LockBits时AccessViolation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想更多更快的比较类似的图像使用LockBits方法

I would like to compare the similar images more faster using LockBits method as follows

using System; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; public class CompareImages { public static void Main ( String[] args ) { Bitmap bm1 = new Bitmap ( "PB270029.JPG" ); Console.WriteLine ( bm1.PixelFormat.ToString() ); int width = bm1.Width; int height = bm1.Height; Console.WriteLine ( "width = " + width + " height = " + height ); Rectangle rect1 = new Rectangle ( 0, 0, width, height ); BitmapData bm1Data = bm1.LockBits ( rect1, ImageLockMode.ReadOnly, bm1.PixelFormat ); Console.WriteLine ( "stride = " + bm1Data.Stride ); IntPtr bm1Ptr = bm1Data.Scan0; int bytes = Math.Abs(bm1Data.Stride) * height; Console.WriteLine ( "bytes = " + bytes ); byte[] rgbValues1 = new byte [ bytes ]; Marshal.Copy ( bm1Ptr, rgbValues1, 0, bytes ); Console.WriteLine ( "After 1st Marshal.Copy ..." ); Bitmap bm2 = new Bitmap ( "PA050164.JPG" ); Rectangle rect2 = new Rectangle ( 0, 0, bm2.Width, bm2.Height ); BitmapData bm2Data = bm2.LockBits ( rect2, ImageLockMode.ReadOnly, bm2.PixelFormat ); IntPtr bm2Ptr = bm2Data.Scan0; byte[] rgbValues2 = new byte [ Math.Abs(bm2Data.Stride) * bm2.Height ]; Marshal.Copy ( bm2Ptr, rgbValues2, 0, rgbValues2.Length ); } }

但在在发生第二Marshal.Copy的AccessViolationException:

but during the second Marshal.Copy the AccessViolationException is occurred:

C:\CompareImages>csc CompareImages.cs Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1 Copyright (C) Microsoft Corporation. All rights reserved. C:\CompareImages>CompareImages.exe Format24bppRgb width = 3648 height = 2736 stride = 10944 bytes = 29942784 After 1st Marshal.Copy ... Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at System.Runtime.InteropServices.Marshal.CopyToManaged(IntPtr source, Object destination, Int32 startIndex, Int32 length) at CompareImages.Main(String[] args)

什么是错在我的计划?

感谢。

推荐答案

我一直在寻找到了几个小时了类似的问题,现在,我想我已经找到了可能是你的问题。我猜你的位图可能存储在稍有不同的格式。位图可以向前或向后存储。向后储存时步幅将是负面的。然而,SCAN0总是指向扫描的第一行,即第一像素不会第一个字节数组中

I've been looking into a similar issue for a few hours now, and I think I've found what might be your problem. I'm guessing your bitmaps might be stored in slightly different formats. Bitmaps can be stored either forwards or backwards. Stride will be negative when stored backwards. However, Scan0 will always point to the first line of the scan, ie, the first pixel NOT the first byte in the array.

因此,在一个向后扫描的位图,SCAN0 + ABS(步幅) - 1是阵列中的最后一个字节。 SCAN0 +步速将永远是第二行的开始,所以如果步幅是否定它的工作原理向后和积极向前会的工作。

Therefore, in a backwards scan bitmap, Scan0 + Abs(Stride) - 1 is the last byte in the array. Scan0 + Stride will always be the start of the second line, so if stride is negative it works backwards and positive will work forwards.

如果你这样做Marshal.Copy(bm2Ptr ,rgbValues2,0,rgbValues2.Length)为负的步伐,这将最后的扫描线进入访问冲突领土之前复制。下面的代码将任何位图转换成一个向后扫描的byte [](只是因为这是我与工作)。我猜你已经固定/现在工作圆你的问题,但希望这可以帮助别人。

If you do Marshal.Copy(bm2Ptr, rgbValues2, 0, rgbValues2.Length) with a negative stride, this will copy the last scanline before entering access violation territory. The following code will convert any bitmap into a backwards scan byte[] (just because that's what I was working with). I'm guessing you've fixed / worked round your problems by now, but hopefully this helps others.

private byte[] BitmapToByteArray2(Bitmap bmp) { // Lock the bitmap's bits. Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat); int absStride = Math.Abs(bmpData.Stride); int bytes = absStride * bmp.Height; // Declare an array to hold the bytes of the bitmap. byte[] rgbValues = new byte[bytes]; for (int i = 0; i < bmp.Height; i++) { IntPtr pointer = new IntPtr(bmpData.Scan0.ToInt32() + (bmpData.Stride * i)); System.Runtime.InteropServices.Marshal.Copy(pointer, rgbValues, absStride * (bmp.Height - i - 1), absStride); } // Unlock the bits. bmp.UnlockBits(bmpData); return rgbValues; }

更多推荐

使用LockBits时AccessViolation

本文发布于:2023-11-11 16:54:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1579026.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:LockBits   AccessViolation

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!