Converting bitmap to special gray scale byte array
我需要在内存中创建一个图像(可以是巨大的图像!)从中提取宽度x高度的字节数组。每个字节的值必须为0-255(256个灰度值:白色为0,黑色为255)。创建图像的部分很容易,下面是我的代码的一个简单示例:
1 2 3 4 | img = new Bitmap(width, height); drawing = Graphics.FromImage(img); drawing.Clear(Color.Black);// paint the background drawing.DrawString(text, font, Brushes.White, 0, 0); |
问题是将它转换为"我的"特殊灰度字节数组。当我使用除Format8bpindexed之外的任何像素格式时,我从位图中得到的字节数组的大小与我需要的大小(宽度*长度)不符,因此我需要一个花费太多时间的转换。当我使用format8bpindexed时,我得到的字节数组非常快并且大小正确,但是每个字节/像素都是0-15。
更改位图调色板没有影响:
1 2 3 4 5 | var pal = img.Palette; for (int i = 1; i < 256; i++){ pal.Entries[i] = Color.FromArgb(255, 255, 255); } img.Palette = pal; |
号
知道怎么做吗?
编辑:完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | // 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; } |
你可能想分两步来完成。首先,创建原始图像的16bpp灰度副本,如"将图像转换为灰度"中所述。
然后,使用适当的颜色表创建8bpp图像,并将16bpp灰度图像绘制到该图像上。这将为您进行转换,将16位灰度值转换为256种不同的颜色。
然后你应该有一个8bpp的图像,有256种不同的灰度。然后可以调用锁位来访问位图位,该位图位将是0到255范围内的索引值。