0

I have seen similar posts on Stack Overflow, but none with quite the same as what I am trying to do. That's why I made a new question.

I am trying to OCR a screenshot by comparing small parts of the screen to bitmaps of alphanumeric characters. (For the purpose of this question, assume that that is an acceptable method of OCR - I know it's really not a good or efficient method at all). I am using the lockbits method to run the comparisons faster (Disclaimer: Everything I know about the lockbits method [including Marshal] I learned from StackOverflow/Google last night ... so not much). When I try to run the code, I get a System.AccessViolation Exception that says "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

The error occurs on the System.Runtime.InteropServices.Marshal.Copy(bmd1.Scan0, b1bytes, 0, bytes); line below. Can anyone tell me why I am getting this error? And how to avoid it?

(In the code below, RTA is a screen-capture, and the numbers array contains bitmaps of the numbers 0 - 9)

Much thanks in advance!

void OCRByComparison()
    {
        Rectangle crop = new Rectangle(0, 0, 9, 10);

        int bytes = RTA.Width * RTA.Height * (Image.GetPixelFormatSize(RTA.PixelFormat) / 8);
        byte[] b1bytes = new byte[bytes];
        byte[] b2bytes = new byte[bytes];

        for(int i = 1; i < RTA.Width - 11; i++)
        {
            for(int j = 0; j < RTA.Height - 12; j++)
            {
                crop.Location = new Point(i,j);
                Bitmap croppedBitmap = RTA.Clone(crop, RTA.PixelFormat);


                int percentEqual = 0;
                for(int n = 0; n < numbers.Length; n++)
                {
                    BitmapData bmd1 = RTA.LockBits(crop, ImageLockMode.ReadOnly, RTA.PixelFormat);
                    BitmapData bmd2 = numbers[n].LockBits(crop, ImageLockMode.ReadOnly, numbers[n].PixelFormat);

                    System.Runtime.InteropServices.Marshal.Copy(bmd1.Scan0, b1bytes, 0, bytes);
                    System.Runtime.InteropServices.Marshal.Copy(bmd2.Scan0, b2bytes, 0, bytes);

                    for (int m = 0; m < bytes; m++)
                    {
                        if (b1bytes[m] == b2bytes[m])
                        {
                            percentEqual++;
                        }
                    }

                    RTA.UnlockBits(bmd1);
                    numbers[n].UnlockBits(bmd2);
                }
            }
        }
    }
BrianH
  • 337
  • 1
  • 6
  • 12
  • Several bugs, you are not dealing with *stride* correctly and you are a long, long way off from getting OCR working. But the crashing bug is because those numbers[] bitmaps don't have the same size and pixel format at the screenshot. So you can't use *bytes* to copy their pixels. – Hans Passant Oct 22 '15 at 19:53
  • @HansPassant Thanks for the reply. I'm not sure I'm even using stride, but I've seen that in some other people's codes. To address your comment though, when I create my BitmapData, doesn't that crop both images so that they are the same size? – BrianH Oct 22 '15 at 19:59
  • You are not cropping correctly either. You'll have to throw this away and think about the code first. Get a sheet of paper, your screenshot. And cut a small rectangle, your letter. Move the letter across the paper, step-by-step horizontally and vertically, your OCR test. Write the code to match that, paying attention to the sizes of the sheet and the letter and the location of the letter. – Hans Passant Oct 22 '15 at 20:07

0 Answers0