Страницы

Поиск по вопросам

вторник, 31 марта 2020 г.

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

#c_sharp #net #изображения #bitmap #обработка_изображений


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

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


Ответы

Ответ 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

Комментариев нет:

Отправить комментарий