我需要在内存中创建一个图像(可以是巨大的图像!)并从中提取宽度为x高度的字节数组。每个字节的值必须为0-255(256个灰度值:0表示白色,255表示黑色)。 创建图像的部分很简单,这是我的代码的一个简单示例:
img = new Bitmap(width, height);
drawing = Graphics.FromImage(img);
drawing.Clear(Color.Black);// paint the background
drawing.DrawString(text, font, Brushes.White, 0, 0);
问题是将其转换为“我的”特殊灰度字节数组。当我使用除了Format8bppIndexed之外的任何像素格式时,我从位图获得的字节数不是我需要的大小(宽度*长度),所以我需要一个花费太多时间的转换。当我使用Format8bppIndexed时,我得到的字节数组非常快,而且大小合适,但每个字节/像素都是0-15。
更改位图调色板没有任何影响:
var pal = img.Palette;
for (int i = 1; i < 256; i++){
pal.Entries[i] = Color.FromArgb(255, 255, 255);
}
img.Palette = pal;
知道该怎么做吗?
编辑:完整代码:
// assume font can be Times New Roman, size 7500!
static private Bitmap DrawText(String text, Font font)
{
//first, create a dummy bitmap just to get a graphics object
var img = new Bitmap(1, 1);
var drawing = Graphics.FromImage(img);
//measure the string to see how big the image needs to be
var textSize = drawing.MeasureString(text, font);
//free up the dummy image and old graphics object
img.Dispose();
drawing.Dispose();
//create a new image of the right size (must be multiple of 4)
int width = (int) (textSize.Width/4) * 4;
int height = (int)(textSize.Height / 4) * 4;
img = new Bitmap(width, height);
drawing = Graphics.FromImage(img);
// paint the background
drawing.Clear(Color.Black);
drawing.DrawString(text, font, Brushes.White, 0, 0);
var bmpData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
var newBitmap = new Bitmap(width, height, bmpData.Stride, PixelFormat.Format8bppIndexed, bmpData.Scan0);
drawing.Dispose();
return newBitmap;
}
private static byte[] GetGrayscleBytesFastest(Bitmap bitmap)
{
BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
int numbytes = bmpdata.Stride * bitmap.Height;
byte[] bytedata = new byte[numbytes];
IntPtr ptr = bmpdata.Scan0;
Marshal.Copy(ptr, bytedata, 0, numbytes);
bitmap.UnlockBits(bmpdata);
return bytedata;
}
答案 0 :(得分:1)
您可能希望分两步完成此操作。首先,按Convert an image to grayscale。
中所述创建原始图像的16bpp灰度副本然后,使用适当的颜色表创建8bpp图像,并将16bpp灰度图像绘制到该图像上。这将为您进行转换,将16位灰度值转换为256种不同的颜色。
然后你应该有一个带有256种不同灰度的8bpp图像。然后,您可以调用LockBits来访问位图位,这将是0到255范围内的索引值。