Трябва да създам изображение в паметта (може да бъде огромно изображение!) и да извлека от него байтов масив с размер ширина 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;
}
pal.Entries[i] = Color.FromArgb(i, i, i);
от 0-255. В останалия свят 0=черно и 255=бяло. Можете ли да ни покажете истинския код за създаване на Format8bppIndexed изображение? Гледал ли си lockbits? Необходимо е да се правят нещата бързо. - person TaW   schedule 06.08.2014