1

I am trying to convert an array of integers in to a bitmap. I have an array of integers in range [0 - 4095] and I want to display them in to a bitmap, than have the user pick an area in the bitmap make a copy of that area and then get the integers back.

I have code that works for cutting the area of the bitmap, but I am having problems with making the bitmap with values as high as 4095, and getting values back from the bitmap as high as 4095.

public Bitmap InttoBitmap(int[] array)
{
    unsafe
    {
        int[] pixels = new int[array.Length];
        for (int i = 0; i < keepWidth * keepHeight; i++)
        {
            pixels[i] = array[i] * 64;
        }
        IntPtr pixptr = Marshal.AllocHGlobal(keepWidth * keepHeight * 2);
        Marshal.Copy(pixels, 0, pixptr, keepWidth * keepHeight);
        Bitmap bitmap = new Bitmap(keepWidth, keepHeight, 2 * keepWidth, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale, pixptr);

        return bitmap;
    }
}

I get a run time error at:

Marshal.Copy(pixels, 0, pixptr, keepWidth * keepHeight);

it says:

System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

update:

 double Average_intensity2(Bitmap bmp)
    {

        double[,] image;
        double answer = 0;
        image = imageToByteArray(bmp);
        double l = 0;

        for (int y = 0; y < bmp.Height; y++)
        {
            for (int x = 0; x < bmp.Width; x++)
            {
                answer = answer + image[y,x];

                l++;
            }
        }
        answer = answer / l;
        return answer;
    }
4
  • It looks like you want to work with the bitmap data directly. Are you locking/unlocking the bitmap? You do realize that an int is 32-bits while a 16bpp is a ushort right? Commented Jun 18, 2019 at 18:26
  • 1
    I don't understand what you think that code is going to do. Are you trying to create an image file? Display something in a UI? WinForm? UWP? A web page. I suggest starting with a graphics book or tutorial. Commented Jun 18, 2019 at 18:28
  • Possible duplicate of How to Convert 2-D array into Image in c# Commented Jun 18, 2019 at 18:32
  • You use Format16bppGrayScale, which doesn't work in .Net. If it's indeed a grayscale image, you could just shift it down, show a simplified 8bpp gray image for selecting the area, and then just look up the corresponding chunk in your original data. Commented Jul 6, 2019 at 13:25

1 Answer 1

2

This answer should correct the System.AccessViolationException being thrown.

Marshal.AllocHGlobal takes the size in bytes.

Allocates memory from the unmanaged memory of the process by using the specified number of bytes.

Let's say that keepWidth = 10 and keepHeight = 10.

You would need to allocate enough space for 10 * 10 = 100 32-bit integers, which would be 10 * 10 * 4 = 400 bytes.

But, you're only allocating 10 * 10 * 2 = 200 bytes. Then, you're trying to copy 100 32-bit integers (400 bytes) into that 200 byte space.

This example will go from an int[] where each item in the array represents a single, RGB pixel in a bitmap. Then it will take the Bitmap and go back to an int[] containing the pixel data.

I'm no expert on this, not by a long shot. I used TheCodeKing's answer from this question to figure out how to get the pixel data from the Bitmap (the BitmapToInts function).

using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Example
{
   class Program
   {
      static void Main(string[] args)
      {
         IntPtr bitmapData = IntPtr.Zero; //Declaring it here and passing it to IntsToBitmap because it needs to be freed.
         try
         {
            int[] pixels = new int[32 * 32]; //32x32 bitmap.
            for (int i = 0; i < pixels.Length; i++)
            {
               pixels[i] = 4080;
            }
            var bmp = IntsToBitmap(pixels, 32, 32, out bitmapData);
            //bmp.Save("SomefilePath") //If you want to see the bitmap.
            var bmpPixels = BitmapToInts(bmp, 0, 0, 32, 32);
            bmp.Dispose();
         }
         finally
         {
            if (bitmapData != IntPtr.Zero)
            {
               Marshal.FreeHGlobal(bitmapData);
            }
         }
      }

      static int[] BitmapToInts(Bitmap bitmap, int x, int y, int width, int height)
      {
         var bitmapData = bitmap.LockBits(
            new Rectangle(x, y, width, height), 
            System.Drawing.Imaging.ImageLockMode.ReadOnly, 
            bitmap.PixelFormat);
         var lengthInBytes = bitmapData.Stride * bitmapData.Height;

         int[] pixels = new int[lengthInBytes / 4];
         Marshal.Copy(bitmapData.Scan0, pixels, 0, pixels.Length);
         bitmap.UnlockBits(bitmapData);
         return pixels;
      }

      static Bitmap IntsToBitmap(int[] pixels, int width, int height, out IntPtr bitmapData)
      {
         bitmapData = Marshal.AllocHGlobal(width * height * 4);
         Marshal.Copy(pixels, 0, bitmapData, pixels.Length);
         return new Bitmap(width, height, 4 * width, System.Drawing.Imaging.PixelFormat.Format32bppArgb, bitmapData);
      }
   }
}
Sign up to request clarification or add additional context in comments.

5 Comments

wait is not working. sorry about that. I did not get any errors, so I thought it was. but when I cover my camera the video should turn black, but it is not. The values coming in are 0s, but the bitmap is still white. so that means it us not working.
If you're using PixelFormat.Format32bppArgb then a value of 0 will be transparent. You need to use 0xFF000000 (-16777216) to get a black pixel. Or use PixelFormat.Format32bppRgb.
ok so that turned my 4080 Value in to a blue color. however, I can cover the camera and get black. but when I convert the bitmap back in to a integer value, I get 85, which I think is blue. I am new to this, but can you store a number greater than 255, in a bitmap ? because so far nothing I have tried seem to work.
I'm afraid I'm no expert either, but as long as the PixelFormat is more than 8 bits per pixel, I don't see why not. It doesn't seem like your code which takes the Bitmap to an int[] has been posted? I've added an example that does the whole round trip, and the ints I get back from the Bitmap are all 4080. Hopefully it helps.
I added the code for my bitmap to double [] conversion

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.