Я хочу получить большинство, раскрашивают фоновое изображение в.NET. Действительно ли это возможно?
Возвращает средний цвет изображения.
static Color AverageColor(string fileName)
{
using (var bmp = new Bitmap(fileName))
{
int width = bmp.Width;
int height = bmp.Height;
int red = 0;
int green = 0;
int blue = 0;
int alpha = 0;
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
{
var pixel = bmp.GetPixel(x, y);
red += pixel.R;
green += pixel.G;
blue += pixel.B;
alpha += pixel.A;
}
Func<int, int> avg = c => c / (width * height);
red = avg(red);
green = avg(green);
blue = avg(blue);
alpha = avg(alpha);
var color = Color.FromArgb(alpha, red, green, blue);
return color;
}
}
При небезопасном доступе указателя будет возвращен средний цвет изображения. Примечание: код адаптирован только для 24bppRgb, может быть адаптирован для других форматов пикселей.
unsafe static Color GetColor(string filename)
{
using (var image = (Bitmap)Bitmap.FromFile(filename))
{
if (image.PixelFormat != PixelFormat.Format24bppRgb) throw new NotSupportedException(String.Format("Unsupported pixel format: {0}", image.PixelFormat));
var pixelSize = 3;
var bounds = new Rectangle(0, 0, image.Width, image.Height);
var data = image.LockBits(bounds, ImageLockMode.ReadOnly, image.PixelFormat);
long r = 0;
long g = 0;
long b = 0;
for (int y = 0; y < data.Height; ++y)
{
byte* row = (byte*)data.Scan0 + (y * data.Stride);
for (int x = 0; x < data.Width; ++x)
{
var pos = x * pixelSize;
b += row[pos];
g += row[pos + 1];
r += row[pos + 2];
}
}
r = r / (data.Width * data.Height);
g = g / (data.Width * data.Height);
b = b / (data.Width * data.Height);
image.UnlockBits(data);
return Color.FromArgb((int)r, (int)g, (int)b);
}
}
Предполагая, что вы характеризуете цвет каждого пикселя с помощью RGB (по сравнению, скажем, с CMYK ), вы можете построить 3D-массив (по одному измерению для R, G и B). Затем определитесь с количеством ячеек, которое вы хотите иметь в каждом измерении - чем больше ячеек, тем больше различий вы делаете между похожими оттенками.
Как только это будет сделано, просто выполните итерацию по растровому представлению вашего изображения, суммируя # пикселей, которые попадают в каждую из ячеек в вашем трехмерном массиве. Ячейка с наибольшей суммой будет преобладающим цветом.
Вы, вероятно, захотите сделать свой алгоритм легко настраиваемым для # интервалов в каждом измерении, чтобы вы могли регулировать, насколько он различает похожие цвета.
image = new Bitmap("C:\\test.bmp", true);
int x, y;
// Loop through the images pixels to product 3d histogram
for(x=0; x<image.Width; x++)
{
for(y=0; y<image.Height; y++)
{
Color pixelColor = image.GetPixel(x, y);
// Increment color count in appropriate cell of your 3d histogram here
...
}
}
Вы можете пролистать все пиксели изображения и использовать метод getPixel для определения значения RGB.Затем можно создать словарь, в который будет храниться значение ARGB вместе с счетчиком. Затем вы можете увидеть, какое значение ARGB больше всего присутствует на изображении.
var list = new Dictionary<int, int>();
Bitmap myImage = (Bitmap)Bitmap.FromFile("C:/test.jpeg");
for (int x = 0; x < myImage.Width; x++)
{
for (int y = 0; y < myImage.Height; y++)
{
int rgb = myImage.GetPixel(x, y).ToArgb();
if (!list.ContainsKey(rgb))
list.Add(rgb, 1);
else
list[rgb]++;
}
}
Как указывалось, это не имеет симпатии к подобным цветам. Если вы хотите более «общий» цвет большинства, у вас может быть порог сходства. Например, вместо:
if (!list.ContainsKey(rgb))
list.Add(rgb, 1);
else
list[rgb]++;
вы могли бы сделать:
var added = false;
for (int i = 0; i < 10; i++)
{
if (list.ContainsKey(rgb+i))
{
list[rgb+i]++;
added = true;
break;
}
if (list.ContainsKey(rgb-i))
{
list[rgb-i]++;
added = true;
break;
}
}
if(!added)
list.Add(rgb, 1);
Вы могли бы поднять порог 10 до того, что вам нужно.
Вы также можете найти эту задачу алгоритма при переполнении стека полезным:
Проблема алгоритма : Создание цветовой схемы из изображения
Также рассмотрите возможность создания гистограммы изображения - и взяв наивысший цвет в качестве «основного цвета»: http://www.phpclasses.org/browse/file/15953 .html