Преобразование изображения в оттенки серого
Есть ли способ конвертировать изображение в оттенки серого размером 16 бит на пиксель, вместо того, чтобы устанавливать яркость каждого из компонентов r, g и b. В настоящее время у меня есть bmp из файла.
Bitmap c = new Bitmap("filename");
Я хочу битмап d, то есть черно-белую версию c. Я вижу конструктор, который включает System.Drawing.Imaging.PixelFormat, но я не понимаю, как его использовать. Я новичок в обработке изображений и соответствующих библиотеках С#, но имею средний опыт работы с С#.
Любая помощь, ссылка на онлайн-источник, подсказка или предложение будут оценены.
EDIT: d - черно-белая версия c.
Ответы
Ответ 1
"Мне нужен битмап d, это оттенки серого. Я вижу конструктора, который включает System.Drawing.Imaging.PixelFormat, но я не понимаю, как использовать это."
Вот как это сделать
Bitmap grayScaleBP = new
System.Drawing.Bitmap(2, 2, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);
EDIT: Чтобы преобразовать в оттенки серого
Bitmap c = new Bitmap("fromFile");
Bitmap d;
int x, y;
// Loop through the images pixels to reset color.
for (x = 0; x < c.Width; x++)
{
for (y = 0; y < c.Height; y++)
{
Color pixelColor = c.GetPixel(x, y);
Color newColor = Color.FromArgb(pixelColor.R, 0, 0);
c.SetPixel(x, y, newColor); // Now greyscale
}
}
d = c; // d is grayscale version of c
Более быстрая версия из switchonthecode следуйте ссылке для полного анализа:
public static Bitmap MakeGrayscale3(Bitmap original)
{
//create a blank bitmap the same size as original
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
//get a graphics object from the new image
Graphics g = Graphics.FromImage(newBitmap);
//create the grayscale ColorMatrix
ColorMatrix colorMatrix = new ColorMatrix(
new float[][]
{
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
//create some image attributes
ImageAttributes attributes = new ImageAttributes();
//set the color matrix attribute
attributes.SetColorMatrix(colorMatrix);
//draw the original image on the new image
//using the grayscale color matrix
g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
//dispose the Graphics object
g.Dispose();
return newBitmap;
}
Ответ 2
Bitmap d = new Bitmap(c.Width, c.Height);
for (int i = 0; i < c.Width; i++)
{
for (int x = 0; x < c.Height; x++)
{
Color oc = c.GetPixel(i, x);
int grayScale = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11));
Color nc = Color.FromArgb(oc.A, grayScale, grayScale, grayScale);
d.SetPixel(i, x, nc);
}
}
Таким образом, он также поддерживает альфа-канал.
Наслаждайтесь.
Ответ 3
Существует статический метод в классе ToolStripRenderer
с именем CreateDisabledImage
.
Его использование так же просто, как:
Bitmap c = new Bitmap("filename");
Image d = ToolStripRenderer.CreateDisabledImage(c);
Он использует немного другую матрицу, чем та, что в принятом ответе, и дополнительно умножает ее на прозрачность значения 0,7, поэтому эффект немного отличается от оттенка серого, но если вы хотите просто сделать изображение серым, оно самое простое и лучшее решение.
Ответ 4
Ни один из приведенных выше примеров не создает 8-битные (8bpp) растровые изображения. Некоторое программное обеспечение, такое как обработка изображений, поддерживает только 8bpp. К сожалению, библиотеки MS.NET не имеют решения. Формат PixelFormat.Format8bppIndexed выглядит многообещающим, но после многих попыток я не смог заставить его работать.
Чтобы создать истинный 8-битный растровый файл, вам необходимо создать соответствующие заголовки. В конечном итоге я нашел Grayscale library для создания 8-битных растровых (BMP) файлов. Код очень прост:
Image image = Image.FromFile("c:/path/to/image.jpg");
GrayBMP_File.CreateGrayBitmapFile(image, "c:/path/to/8bpp/image.bmp");
Код для этого проекта далеко не хорош, но он работает, с одной маленькой простой в установке проблемой. Автор жестко закодировал разрешение изображения до 10x10. Программам обработки изображений это не нравится. Исправление открыто GrayBMP_File.cs(да, фанки имя файла, я знаю) и заменить строки 50 и 51 кодом ниже. В примере задано разрешение 200x200, но вы должны изменить его на правильный номер.
int resX = 200;
int resY = 200;
// horizontal resolution
Copy_to_Index(DIB_header, BitConverter.GetBytes(resX * 100), 24);
// vertical resolution
Copy_to_Index(DIB_header, BitConverter.GetBytes(resY * 100), 28);
Ответ 5
Подведем итог нескольким пунктам:
Есть несколько пиксельных опций, которые, будучи простыми, просто не быстрые.
Комментарий @Luis ', ссылающийся на: (архивированный) https://web.archive.org/web/20110827032809/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale превосходный.
Он использует три разных варианта и включает тайминги для каждого.
Ответ 6
Ниже приведено простейшее решение:
Bitmap bt = new Bitmap("imageFilePath");
for (int y = 0; y < bt.Height; y++)
{
for (int x = 0; x < bt.Width; x++)
{
Color c = bt.GetPixel(x, y);
int r = c.R;
int g = c.G;
int b = c.B;
int avg = (r + g + b) / 3;
bt.SetPixel(x, y, Color.FromArgb(avg,avg,avg));
}
}
bt.Save("d:\\out.bmp");