Подтвердить что ты не робот

Как инвертировать цвет/цвет?

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

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

const int RGBMAX = 255;

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

Ответ 1

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

В вашем коде присутствует "негативный" цвет.

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

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

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

Ответ 2

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

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

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

Ответ 3

Попробуйте следующее:

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

Ответ 4

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

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

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

Ответ 5

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

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

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

Ответ 6

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

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

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

Код сдвига на 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);
    }
}

Ответ 7

Самый простой и ленивый способ заставить меня работать с наличием не только тройных 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 или близко к нему.