it-swarm.com.ru

Как я могу инвертировать цвет?

Я знаю, что это не будет напрямую инвертировать цвет, оно будет просто «противодействовать» ему. Мне было интересно, если кто-нибудь знает простой способ (несколько строк кода), чтобы инвертировать цвет из любого данного цвета?

На данный момент у меня есть это (которое не совсем соответствует определению инвертирования, потому что, если я передам ему серый/серый цвет, он вернет что-то очень похожее, например, 127, 127, 127):

const int RGBMAX = 255;

Color InvertMeAColour(Color ColourToInvert)
{
    return Color.FromArgb(RGBMAX - ColourToInvert.R, 
      RGBMAX - ColourToInvert.G, RGBMAX - ColourToInvert.B);
}
35
ThePower

Это зависит от того, что вы подразумеваете под "инвертированием" цвета

Ваш код обеспечивает «отрицательный» цвет.

Вы ищете для преобразования красный в голубой, зеленый в фиолетовый, синий в желтый (и так далее)? Если это так, вам нужно конвертировать цвет RGB в режиме HSV (вы найдете здесь , чтобы выполнить преобразование).

Затем вам просто нужно инвертировать значение Hue (изменить Hue на 360-Hue) и преобразовать обратно в режим RGB.

Правка: как отметил Алекс Семенюк, изменение Hue на (Hue + 180) % 360 является лучшим решением (оно не инвертирует оттенок, но находит противоположный цвет на цветовом круге)

47
ThibThib

Ты можешь использовать :

MyColor=Color.FromArgb(MyColor.ToArgb()^0xffffff);

Это инвертирует MyColor.

17
Remy

Попробуй это:

uint InvertColor(uint rgbaColor)
{
    return 0xFFFFFF00u ^ rgbaColor; // Assumes alpha is in the rightmost byte, change as needed
}
10
korona

Если вы хотите изменить каждый цвет, попробуйте вращательную функцию (смещение или сложение), а не функцию переворачивания (инвертирование). Другими словами, рассмотрим диапазон от 0 до 255 для каждого отдельного цвета (красного, зеленого и синего), который должен быть обернут, соединен на кончиках как круг значений. Затем сдвиньте каждый цвет вокруг круга, добавив некоторое значение и выполнив мод 256. Например, если ваше начальное значение для красного равно 255, и вы добавляете 1, вы получите 0. Если вы сместите все три цвета на 128, вы получите резко отличающиеся значения для каждого оригинального цвета на картинке, даже серых. Серый 127, 127, 127 становится белым 255, 255, 255. Серый 128, 128, 128 становится черным 0, 0, 0. Существует такой фотографический эффект, как тот, который называется Соляризация, случайно обнаруженный Ман Рэем в 1930-х годах.

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

Вы также можете выполнять вращательные операции с оттенком, смещая оттенок каждого исходного цвета на некоторую величину на окружности оттенка, что изменяет все цвета без изменения яркости, поэтому тени по-прежнему выглядят как тени, делая людей похожими на Симпсонов или Смурфов для пример.

Код для сдвига на 128 может выглядеть так:

public static Color Invert(this Color c) => Color.FromArgb(c.R.Invert(), c.G.Invert(), c.B.Invert());

public static byte Invert(this byte b) {
    unchecked {
        return (byte)(b + 128);
    }
}
5
Raxin

Инвертировать биты каждого компонента отдельно:

Color InvertMeAColour(Color ColourToInvert)
{
   return Color.FromArgb((byte)~ColourToInvert.R, (byte)~ColourToInvert.G, (byte)~ColourToInvert.B);
}

Правка: Оператор ~ не работает с байтами автоматически, требуется приведение.

5
Kenan E. K.

То, что у вас уже есть, это RGB-Invert. Существуют и другие способы классификации цветов и, следовательно, другие определения для инверсии цвета. 

Но может показаться, что вам нужен контрастный цвет, и нет простой Инверсии, которая будет работать для всех цветов, включая RGB (127, 127, 127). 

Что вам нужно, это 1) преобразование в HSV (см. Ответ ThibThibs) и инвертирование оттенка, но также 2) проверка того, не должен ли оттенок быть близко к середине, и если это так, перейдите либо к полностью яркому, либо к полностью темному. 

5
Henk Holterman

Самый простой и ленивый способ работы с не только тройным 12-кратным, но и смешанным значением, заключается в следующем:

Color invertedColor= Color.FromArgb(fromColor.ToArgb() ^ 0xffffff);

if (invertedColor.R > 110 && invertedColor.R < 150 &&
    invertedColor.G > 110 && invertedColor.G < 150 &&
    invertedColor.B > 110 && invertedColor.B < 150)
{
    int avg = (invertedColor.R + invertedColor.G + invertedColor.B) / 3;
    avg = avg > 128 ? 200 : 60;
    invertedColor= Color.FromArgb(avg, avg, avg);
}

Теперь invertedColor имеет цвет, отличный от оригинала, даже если мы имеем значение цвета 128, 128, 128 или близкое к нему.

1
Christos Lytras

Я создал эту простую функцию для VB.NET:

Public Shared Function Invert(ByVal Culoare As Color) As Color
    Return Color.FromArgb(Culoare.ToArgb() Xor &HFFFFFF)
End Function

И этот для C #:

public static Color Invert(Color Culoare)
{
    return Color.FromArgb(Culoare.ToArgb() ^ 0xFFFFFF);
}
0
Alexandru-Codrin Panaite