Оставить только необходимые цвета с Bitmap

155
05 августа 2018, 22:10

Как в Bitmap оставить только необходимые цвета пикселей, а остальные превратить, например, в чёрный цвет?

Конечно, хотелось бы решение пошустрей.

Answer 1

Самый простой вариант - через GetPixel и SetPixel, но будет работать довольно медленно.

Лучше использовать Scan0 и преобразовать картинку в массив intов, соответствующих цвету каждого пикселя - для этого подходит формат PixelFormat.Format32bppArgb - в нём цвета представлены 4 байтами и в intе тоже 4 байта.

Ниже код обработки на VB.NET, его можно легко переписать на C#.

Этот код заменяет один цвет на другой, но позволяет при сравнении игнорировать альфа-канал (и сохранять его при замене). Если нужно какое-либо ещё условие, то надо заменить соответствующее сравнение и присваивание.

Public Shared Sub ReplaceColor(ByVal Bmp As Bitmap, ByVal OldColor As Color, ByVal NewColor As Color, Optional ByVal IgnoreAlpha As Boolean = False)
  Dim BmpData As BitmapData = Bmp.LockBits(New Rectangle(Nothing, Bmp.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
  Dim ArgbData(BmpData.Stride * BmpData.Height / 4 - 1) As Integer
  Dim Mask As Integer = If(IgnoreAlpha, (1 << 24) - 1, -1), NotMask As Integer = Not Mask
  Dim OldVal As Integer = ((((((CInt(OldColor.A) << 8) Or OldColor.R) << 8) Or OldColor.G) << 8) Or OldColor.B) And Mask
  Dim NewVal As Integer = ((((((CInt(NewColor.A) << 8) Or NewColor.R) << 8) Or NewColor.G) << 8) Or NewColor.B) And Mask
  Marshal.Copy(BmpData.Scan0, ArgbData, 0, ArgbData.Length)
  For Q As Integer = 0 To ArgbData.Length - 1
    If (ArgbData(Q) And Mask) = OldVal Then ArgbData(Q) = (ArgbData(Q) And NotMask) Or NewVal
  Next Q
  Marshal.Copy(ArgbData, 0, BmpData.Scan0, ArgbData.Length)
  Bmp.UnlockBits(BmpData)
End Sub
READ ALSO
Использование своего UserControl WPF

Использование своего UserControl WPF

Создал свой User Control элементРасставил и настроил там элементы как они должны располагаться, растягиваться

175
Как выгрузить DataGrid в XML?

Как выгрузить DataGrid в XML?

Имеется DataGridЕсть проблемы с выгрузкой содержимого в XML

166
Не отображается UserControl в конструкторе WinForms

Не отображается UserControl в конструкторе WinForms

Cуть проблемы в том что у меня есть три usercontrol-а для трех фигур, два из них отображаются, а один нет(обведен красным, в контроле должно быть видно...

146
Проблема с комбо-бокс-столбцами таблицы

Проблема с комбо-бокс-столбцами таблицы

В таблице есть две колонки, обе они имеют тип DataGridComboBoxColumnВ первой колонке надо показывать выпадающий список из одной коллекции, во второй...

173