Вопрос

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

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

const int RGBMAX = 255;

Color InvertMeAColour(Color ColourToInvert)
{
    return Color.FromArgb(RGBMAX - ColourToInvert.R, 
      RGBMAX - ColourToInvert.G, RGBMAX - ColourToInvert.B);
}
Это было полезно?

Решение

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

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

Вы ищете преобразование красного в голубой, зеленого в фиолетовый, синего в желтый (и так далее)?Если да, вам необходимо преобразовать цвет RGB в ВПГ режим (вы найдете здесь совершить трансформацию).

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

РЕДАКТИРОВАТЬ:как отметил Алекс Семенюк, изменение Hue к (Hue + 180) % 360 лучшее решение (оно не инвертирует оттенок, а находит противоположный цвет на цветовом круге)

Другие советы

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

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

Он инвертирует MyColor.

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

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

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

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

РЕДАКТИРОВАТЬ:Оператор ~ не работает с байтами автоматически, необходимо приведение.

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

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

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

Если вы хотите изменить каждый цвет, попробуйте функцию вращения (смещение или добавление), а не функцию переворота (инвертирование).Другими словами, рассмотрим диапазон от 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);
    }
}

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

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 или близкое к нему.

Я создал эту простую функцию для 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);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top