Преобразование массива int в растровое изображение - PullRequest
0 голосов
/ 18 июня 2019

Я пытаюсь преобразовать массив целых чисел в растровое изображение.У меня есть массив целых чисел в диапазоне [0 - 4095], и я хочу отобразить их в растровом изображении, после чего пользователь выбирает область в растровом изображении, делает копию этой области и затем возвращает целые числа обратно.

У меня есть код, который работает для вырезания области растрового изображения, но у меня возникают проблемы с созданием растрового изображения со значениями до 4095 и получением значений из растрового изображения до 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;
    }
}

Я получаю ошибку во время выполнения по адресу:

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

, там написано:

System.AccessViolationException: 'Попытка чтения или записи в защищенную память.Это часто указывает на то, что другая память повреждена. '

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

1 Ответ

1 голос
/ 18 июня 2019

Этот ответ должен исправить выброшенный System.AccessViolationException.

Marshal.AllocHGlobal принимает размер в байтах.

Выделяет память из неуправляемой памяти процесса, используя указанное количество байтов.

Допустим, что keepWidth = 10 и keepHeight = 10.

Вам потребуется выделить достаточно места для 10 * 10 = 100 32-разрядных целых чисел, которые будут 10 * 10 * 4 = 400 байтов.

Но вы выделяете только 10 * 10 * 2 = 200 байтов.Затем вы пытаетесь скопировать 100 32-битных целых (400 байт) в это 200-байтовое пространство.

Этот пример будет взят из int[], где каждый элемент в массиве представляет один пиксель RGBв растровом изображении.Затем он возьмет Bitmap и вернется к int[], содержащему данные о пикселях.

Я не эксперт в этом, по большому счету.Я использовал ответ TheCodeKing от на этот вопрос , чтобы выяснить, как получить данные пикселей из Bitmap (функция BitmapToInts).

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);
      }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...