Как добраться, большинство раскрашивают изображение?

Я хочу получить большинство, раскрашивают фоновое изображение в.NET. Действительно ли это возможно?

9
задан John 30 March 2010 в 14:04
поделиться

5 ответов

Возвращает средний цвет изображения.

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;
    }
}
5
ответ дан 4 December 2019 в 09:12
поделиться

При небезопасном доступе указателя будет возвращен средний цвет изображения. Примечание: код адаптирован только для 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);
        }
    }

суть: http://gist.github.com/349210

4
ответ дан 4 December 2019 в 09:12
поделиться

Предполагая, что вы характеризуете цвет каждого пикселя с помощью 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
      ...
   }
}
3
ответ дан 4 December 2019 в 09:12
поделиться

Вы можете пролистать все пиксели изображения и использовать метод 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 до того, что вам нужно.

6
ответ дан 4 December 2019 в 09:12
поделиться

Вы также можете найти эту задачу алгоритма при переполнении стека полезным:

Проблема алгоритма : Создание цветовой схемы из изображения

Также рассмотрите возможность создания гистограммы изображения - и взяв наивысший цвет в качестве «основного цвета»: http://www.phpclasses.org/browse/file/15953 .html

5
ответ дан 4 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: