English 中文(简体)
使用洛克比时的隔离
原标题:AccessViolation when using LockBits
  • 时间:2011-01-27 13:32:09
  •  标签:
  • c#

我愿比较使用洛克比办法的类似图像,其速度要更快:

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 );

 }

}

但是,在第二位沼泽中。 • 接收器:

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)

我的方案有什么错误?

感谢。

问题回答

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(Stride)是阵列中最后一批。 斯堪的0+Stide将永远是第二行的开端,因此,如果扼杀是负面的,就会倒退,积极的工作将向前推进。

如果你做 Marsh子(bm2Ptr, rgbValues2, 0, rgbValues2.Length, 的话,这将在进入侵犯领土之前复制最后的扫描。 下面的法典将把任何比图转换成后扫描(因为那是我所从事的工作)。 我猜想到,到现在为止,你已经固定下来/工作了你们的问题,但希望这有助于其他人。

    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;
    }

这对我来说都是如此。 我试图使图像档案失效,但这种说法存在不同的例外。 确实需要一些清洁。

using (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);
    try
    {
        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 ...");
    }
    finally
    {
        bm1.UnlockBits(bm1Data);
    }
}

using (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);
    try
    {
        IntPtr bm2Ptr = bm2Data.Scan0;
        byte[] rgbValues2 = new byte[Math.Abs(bm2Data.Stride) * bm2.Height];
        Marshal.Copy(bm2Ptr, rgbValues2, 0, rgbValues2.Length);
    }
    finally
    {
        bm2.UnlockBits(bm2Data);
    }
}

我测试了该守则,对我来说,该守则是行之有效的。

第一,我对地雷进行了一些随机描述,然后用你幅貌的全貌画。 你们是否可以提供更多有关两幅画面的信息:两幅画面的大小是否相同?

我看到的唯一可能错误是,在复制后,你不叫“UnlockBits”。

条很好地解释了洛克比的职能。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签