Градиенты стиля Heatmap в .NET.

Я пытаюсь создать карту тепла с градиентами, которые выглядят примерно так: enter image description here

На этом изображении показаны три точки, и градиенты хорошо сочетаются вместе.

Вот что я сейчас делаю в моей функции рисования:

public void DrawGradient(int x, int y, Graphics g) {
    using (var ellipsePath = new GraphicsPath()) {

    var bounds = new Rectangle(x, y, 100, 100);
    ellipsePath.AddEllipse(bounds);
    var brush = new PathGradientBrush(ellipsePath);
    Color[] colors = { 
           Color.FromArgb(64, 0, 0, 255), 
           Color.FromArgb(140, 0, 255, 0), 
           Color.FromArgb(216, 255, 255, 0), 
           Color.FromArgb(255, 255, 0, 0) 
       };
    float[] relativePositions = {0f,0.25f,0.5f, 1.0f};
    ColorBlend colorBlend = new ColorBlend();
    colorBlend.Colors = colors;
    colorBlend.Positions = relativePositions;
    brush.InterpolationColors = colorBlend;

    g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;

    g.FillEllipse(brush, bounds);
  }
}

Что создает изображение, подобное этому для двух перекрывающихся точек:

enter image description here

Не смешивается. Как создать эффект смешивания градиента в .NET-чертеже?

Ответ 1

Да, это возможно с & lt; 100 строк .NET и GDI+ код для рисования..:

enter image description here

Вам нужно изменить эти вещи в своем коде:

  • Вам нужно постепенно растушевывать области точек до прозрачного, чтобы вы могли добавить их
  • Вам нужно использовать градиент оттенков серого, чтобы не создавать неправильные, возможно, грязные цвета
  • Как следствие, вам нужно переназначить цвета.

Вот подробности:

Вам нужны два градиента:

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

  • Цветовой градиент перечисляет цвета вашей тепловой карты.

Далее вам нужно одно или несколько растровых изображений с размытыми серыми кругами. Если точечные области одинаковы, один будет делать.

Теперь вы можете нарисовать растровые изображения на целевом растровом изображении. Обязательно установите Graphics.CompositingMode = CompositingMode.SourceOver;. Это приведет к чему-то вроде левого скриншота.

Наконец, вам нужно изменить карту цветов:

Для этого вам нужно настроить ColorMaps:

  • создайте два цветовых списка, один из которых будет отображать цвета в оттенках серого за 256 шагов, а другой - с таким же количеством шагов, что и цвета вашей тепловой карты. Обратите внимание, что списки должны иметь одинаковое количество элементов; однако у каждого из градиентов может быть столько, сколько вам угодно.

Списки цветов можно создать, заполнив Bitmap размером 256x1 пикселей LinearGradientBrush, который использует те же два соответствующих ColorBlends, а затем используя GetPixel, чтобы вытянуть цвета.

После выполнения SetRemapTable мы наконец можем нарисовать тепловую карту, и вуаля, правый скриншот довольно похож, даже без какой-либо настройки, чтобы действительно приблизиться к вашей тепловой карте.

Ваш код

Вот несколько замечаний по поводу недостатков в вашем коде:

  • Вы должны постепенно исчезать из полностью прозрачного. Ваши цвета начинаются с альфа-64, который далек от от "почти прозрачного". Наши глаза очень чувствительны на этом конце шкалы!

Вот градиент оттенков серого, который я использовал, с фоном шахматной доски в стиле фотошопа, чтобы вы могли видеть прозрачность:

enter image description here

  • Другая проблема с вашими цветами в том, что они начинаются с синего цвета; им действительно нужно начинать с белого!

  • Самая фундаментальная проблема - это смешение цветов. Для "тепловой карты" (или "карты профиля" или "карты смещения") нам нужно сложить значения, а не смешать их. Для этого цветовые каналы бесполезны. Цвета являются круглыми, и они, естественно, не поддаются списку возрастающих значений. Если мы используем только альфа-канал, мы можем простым способом ограничить карту "картой яркости", которую мы можем затем раскрасить любым удобным для нас способом.

Обратите внимание, что я предположил, что центральные точки должны быть максимумами. Если это не так, вам нужно уменьшить их до более низкого альфа-значения, чтобы их сложение не переполнялось.

Также обратите внимание, что для действительно важных применений, таких как медицинская или научная визуализация, вы должны пройти весь расчет значений, чтобы вы имели полный контроль над отображением!