Этот ответ должен исправить выброшенный 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);
}
}
}