Изменение оттенка растрового изображения при сохранении общей яркости - PullRequest
5 голосов
/ 27 февраля 2010

Я пытаюсь написать функцию, которая позволит мне смещать красное или синее смещение растрового изображения, сохраняя при этом общую яркость изображения. По существу, растровое изображение с полностью красным смещением будет иметь ту же яркость, что и оригинал, но будет полностью окрашено в красный цвет (т.е. значения G и B будут одинаковыми для всех пикселей). То же самое для синих оттенков (но с равными R и G). Степень смещения спектра должна варьироваться от 0 до 1.

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 03 марта 2010

Вот эффект, который я искал (дерьмовый JPEG, извините):

альтернативный текст http://www.freeimagehosting.net/uploads/d15ff241ca.jpg

Изображение посередине является оригиналом, а боковые изображения полностью смещены в красный, частично смещен красный, частично смещен в синий и полностью смещен, соответственно.

А вот функция, которая производит этот эффект:

public void RedBlueShift(Bitmap bmp, double factor)
{
    byte R = 0;
    byte G = 0;
    byte B = 0;
    byte Rmax = 0;
    byte Gmax = 0;
    byte Bmax = 0;
    double avg = 0;
    double normal = 0;
    if (factor > 1)
    {
        factor = 1;
    }
    else if (factor < -1)
    {
        factor = -1;
    }
    for (int x = 0; x < bmp.Width; x++)
    {
        for (int y = 0; y < bmp.Height; y++)
        {
            Color color = bmp.GetPixel(x, y);
            R = color.R;
            G = color.G;
            B = color.B;
            avg = (double)(R + G + B) / 3;
            normal = avg / 255.0; // to preserve overall intensity
            if (factor < 0) // red-tinted:
            {
                if (normal < .5)
                {
                    Rmax = (byte)((normal / .5) * 255);
                    Gmax = 0;
                    Bmax = 0;
                }
                else
                {
                    Rmax = 255;
                    Gmax = (byte)(((normal - .5) * 2) * 255);
                    Bmax = Gmax;
                }
                R = (byte)((double)R - ((double)(R - Rmax) * -factor));
                G = (byte)((double)G - ((double)(G - Gmax) * -factor));
                B = (byte)((double)B - ((double)(B - Bmax) * -factor));
            }
            else if (factor > 0) // blue-tinted:
            {
                if (normal < .5)
                {
                    Rmax = 0;
                    Gmax = 0;
                    Bmax = (byte)((normal / .5) * 255);
                }
                else
                {
                    Rmax = (byte)(((normal - .5) * 2) * 255);
                    Gmax = Rmax;
                    Bmax = 255;
                }
                R = (byte)((double)R - ((double)(R - Rmax) * factor));
                G = (byte)((double)G - ((double)(G - Gmax) * factor));
                B = (byte)((double)B - ((double)(B - Bmax) * factor));
            }
            color = Color.FromArgb(R, G, B);
            bmp.SetPixel(x, y, color);
        }
    }
}
3 голосов
/ 27 февраля 2010

Для этого вы бы использовали класс ColorMatrix. В этом проекте есть хороший учебник .

...