반응형
라이브러리를 사용하지 않고 C#을 통해서 히트맵을 그려봤습니다. 해당 내용은 스택오버플로우에 질문과 답변을 참고하여 작성하였습니다.
원하는 목표
- 히트맵(Heatmap)을 만들기 위해서 원을 그린다.
- 원은 중첩 가능하며 중첩된 부분은 진한 색으로 표현되어야 한다.
- 빨강에서 시작해서 파랑으로 끝나는 컬러맵(ColorMap)으로 표현되어야 한다.
구현 방법
- 중심이 검은색(Black), 바깥쪽은 투명(Transparent)으로 그라데이션 색상이 들어간 원을 그린다.
- Remap에 사용할 가로 256 * 세로 1의 컬러맵을 2개 생성해서 준비한다.
- Grayscale맵은 검정(Black)에서 투명(Transparent)으로 구성된 컬러맵이다.
- HeatmapColor맵은 빨강(Red)에서 시작해서 투명(Transparent)으로 진행되는 컬러맵이다.
(자연스러운 히트맵 생성을 위해서 중간값을 넣어주자) - SetRemapTable함수를 이용해서 색을 재맵핑(Remap)된다.
예제코드
원 그리기 함수
CenterColor 검정에서 시작해서 SurroundColor가 투명으로 채워진다.
public static void DrawCircle(Graphics grf, int x, int y, int circleSize, int alphaValue)
{
var myEllipse = new Rectangle(x, y, circleSize, circleSize);
using (var gp = new GraphicsPath())
{
gp.AddEllipse(myEllipse);
var pgb = new PathGradientBrush(gp);
pgb.CenterPoint = new PointF(myEllipse.X + myEllipse.Width / 2,
myEllipse.Y + myEllipse.Height / 2);
pgb.CenterColor = Color.FromArgb(alphaValue, Color.Black);
pgb.SurroundColors = new Color[] { Color.FromArgb(0, Color.Transparent) };
grf.FillPath(pgb, gp);
};
}
Grayscale 컬러맵 생성 함수
SetRemapTable함수에 사용할 컬러맵 정보를 생성합니다.
width와 height는 256 * 1 사이즈로 작성합니다.
public static Bitmap CreateGrayscaleMap(int width, int height)
{
Bitmap grayscaleMap = new Bitmap(width, height);
using (Graphics grf = Graphics.FromImage(grayscaleMap))
{
LinearGradientBrush lgb = new LinearGradientBrush(new Rectangle(0, 0, width, height), Color.Black, Color.Transparent, LinearGradientMode.Horizontal);
ColorBlend colorblend = new ColorBlend();
colorblend.Colors = new Color[] { Color.Black, Color.Transparent };
colorblend.Positions = new Single[] { 0.0F, 1.0F };
lgb.InterpolationColors = colorblend;
grf.FillRectangle(lgb, new Rectangle(0, 0, width, height));
}
return grayscaleMap;
}
Heatmap 컬러맵 생성 함수
동일하게 width와 height는 256 * 1 사이즈로 작성합니다.
public static Bitmap CreateHeatColorMap(int width, int height)
{
Bitmap colorListHeatmap = new Bitmap(width, height);
using (Graphics grf = Graphics.FromImage(colorListHeatmap))
{
LinearGradientBrush lgb = new LinearGradientBrush(new Rectangle(0, 0, width, height), Color.Black, Color.Transparent, LinearGradientMode.Horizontal);
ColorBlend colorblend = new ColorBlend();
colorblend.Colors = new Color[] { Color.Red, Color.Yellow, Color.Lime, Color.Cyan, Color.Blue, Color.Transparent };
colorblend.Positions = new Single[] { 0.0F, 0.2F, 0.4F, 0.6F, 0.75F, 1.0F };
lgb.InterpolationColors = colorblend;
grf.FillRectangle(lgb, new Rectangle(0, 0, width, height));
}
return colorListHeatmap;
}
SetRemapTable 함수
var cm = DrawUtil.CreateGrayscaleMap(_colorMapWidth, _colorMapHeight);
var hcm = DrawUtil.CreateHeatColorMap(_colorMapWidth, _colorMapHeight);
ColorMap[] colorMap = new ColorMap[256];
for (int i = 0; i < colorMap.Length; i++)
{
colorMap[i] = new ColorMap();
colorMap[i].OldColor = cm.GetPixel(i, 0);
colorMap[i].NewColor = hcm.GetPixel(i, 0);
}
ImageAttributes imageAttr = new ImageAttributes();
imageAttr.SetRemapTable(colorMap);
해당 함수를 호출하면 grayscale 스타일로 적용되었던 색들이 히트맵에 맞는 지정된 색들로 재맵핑된다.
이제 세부조정을 통해서 원하는 크기와 느낌의 히트맵을 작성하면 된다.
'프로그래밍 > C#' 카테고리의 다른 글
C# 단정밀도(Single Precision), 배정밀도(Double Precision)에 대해서 (7) | 2023.05.11 |
---|---|
C# ProtectedSessionStorage 클래스 (4) | 2023.05.10 |
C# 날짜 서식 지정자(Datetime Format Specifier)에 대해서 (6) | 2023.05.04 |
C# 미리 정의된 Delegate에 대해서 (18) | 2023.04.26 |
인물 탐구 - C#의 아버지 아네르스 하일스베르(Anders Hejlsberg) (14) | 2023.04.24 |
댓글