我正在尝试将整数数组转换为位图。我有一个范围为[0-4095]的整数数组,我想将它们显示在位图中,而不是让用户在位图中选择一个区域来制作该区域的副本,然后取回整数。
我有一些用于剪切位图区域的代码,但是我在制作值高达4095的位图以及从位图获取高达4095的值时遇到了问题。
dcast(test, id ~ class)
我在以下位置遇到运行时错误:
dput(test)
structure(list(class = c("foo", "bar", "baz", "baz", "bar", "foo",
"foo", "foo", "foo"), id = c(1, 1, 1, 2, 2, 2, 3, 3, 3)), row.names = c(NA,
-9L), class = "data.frame")
它说:
System.AccessViolationException:'试图读取或写入受保护的内存。这通常表明其他内存已损坏。'
更新:
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;
}
}
答案 0 :(得分:1)
此答案应更正抛出的System.AccessViolationException
。
Marshal.AllocHGlobal takes the size in bytes.
使用指定的字节数从进程的非托管内存中分配内存。
让我们说keepWidth = 10
和keepHeight = 10
。
您需要为10 * 10 = 100
个32位整数分配足够的空间,该整数将为10 * 10 * 4 = 400
个字节。
但是,您仅分配10 * 10 * 2 = 200
个字节。然后,您尝试将100个32位整数(400个字节)复制到该200个字节的空间中。
此示例将从int[]
开始,其中数组中的每个项目代表位图中的单个RGB像素。然后将使用Bitmap
,然后返回到包含像素数据的int[]
。
我不是这个专家,不是很远。我使用了this question的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);
}
}
}