我正在构建一个程序来生成热图。我正在利用为GDI +编写的代码,但是对于various reasons,我决定将其移至SkiaSharp。
我目前有一个灰度图像图块,其中白色代表最大值,纯黑色是透明的。在GDI + / C#中,我可以快速使用ColorMap
和SetRemapTable
。我已经看过ColorFilter了,但是接缝要使用矩阵变换,而不是我有些武断的重新映射。
SkiaSharp与此类似吗?还是应该手动遍历每个像素并重新着色?
使用GDI +的原始代码:
ImageAttributes imageAttributes = new ImageAttributes();
ColorMap[] remapTable = new ColorMap[256];
Color[] scale = IncandescentHeatScale();
for (int i = 0; i < 256; i++)
{
remapTable[i] = new ColorMap()
{
OldColor = Color.FromArgb(i, i, i),
NewColor = scale[i]
};
}
imageAttributes.SetRemapTable(remapTable);
var outTile = new Bitmap(TileSize, TileSize);
using (var g = Graphics.FromImage(outTile))
{
g.DrawImage(tile, new Rectangle(0, 0, TileSize, TileSize), padding, padding, TileSize, TileSize, GraphicsUnit.Pixel, imageAttributes);
}
相关功能,供参考:
static Color[] GetHeatScale(float[] points, Color[] colors)
{
var bm = new Bitmap(256, 1);
using (Graphics g = Graphics.FromImage(bm))
{
LinearGradientBrush brush = new LinearGradientBrush(new Point(0, 0), new Point(256, 0), colors[0], colors[colors.Length - 1]);
var cb = new ColorBlend();
cb.Colors = colors;
cb.Positions = points;
brush.InterpolationColors = cb;
g.FillRectangle(brush, 0, 0, 256, 1);
}
return Enumerable.Range(0, 256).Select(x => bm.GetPixel(x, 0)).ToArray();
}
static Color[] IncandescentHeatScale()
{
float[] points = new float[] { 0.0f, 0.333f, 0.6666f, 1f };
Color[] colors = new Color[] { Color.Black, Color.DarkRed, Color.Yellow, Color.White };
return GetHeatScale(points, colors);
}
答案 0 :(得分:1)
是的,Skia / SkiaSharp将让您变换颜色。除了使用Matrix变换之外,您还可以使用颜色重映射表。
使用SKColorFilter.CreateTable(alphaRemapTable, redRemapTable, blueRemapTable, greeenRemapTable)
这些表是字节数组,长256个元素。重新映射的工作方式是将起始颜色的成分用作索引,以查找应重新映射到的值,例如。 10个红色将转换为红色数组中索引为10的值。
将null传递给任何参数将使该颜色分量保持不变。
答案 1 :(得分:0)
这是我的解决方案,适用于所有实际上只想快速复制一些代码的人。我知道这个问题已经两年了,但这是您在这个主题上唯一能找到的。此代码将 SKBitmap 转换为彩色位图。
public Bitmap Colorize(SKBitmap bitmap, SKImageInfo info)
{
using (SKSurface surface = SKSurface.Create(info))
{
SKCanvas canvas = surface.Canvas;
using (SKPaint paint = new SKPaint())
{
paint.ColorFilter = CreatePaletteIndex_skia(255);
canvas.DrawBitmap(bitmap, info.Rect, paint);
}
using (SKImage image = surface.Snapshot())
using (SKData data = image.Encode(SKEncodedImageFormat.Png, 100))
using (MemoryStream memoryStream = new MemoryStream(data.ToArray()))
{
Bitmap bm = new Bitmap(memoryStream, false);
return bm;
}
}
}
private static SKColorFilter CreatePaletteIndex_skia(byte Alpha)
{
byte[] R = new byte[256];
byte[] G = new byte[256];
byte[] B = new byte[256];
byte[] A = new byte[256];
string dirExe = System.AppDomain.CurrentDomain.BaseDirectory;
string colorImg = "ColorPalette.png";
string pathColorPalette = dirExe + "Content\\" + colorImg;
Bitmap Palette = (Bitmap)Bitmap.FromFile(pathColorPalette);
// Loop through each pixel and create a new color mapping
for (int X = 0; X <= 255; X++)
{
R[X] = Palette.GetPixel(X, 0).R;
G[X] = Palette.GetPixel(X, 0).G;
B[X] = Palette.GetPixel(X, 0).B;
A[X] = Alpha;
}
SKColorFilter colorFilter = SKColorFilter.CreateTable(A, R, G, B);
return colorFilter;
}
您只需将一张 256 像素宽的渐变图片 (gradient) 放入项目的文件夹中,并通过变量 pathColorPalette 将其链接。
代码基于这个项目,关于如何在没有skia的情况下做到这一点:http://dylanvester.com/2015/10/creating-heat-maps-with-net-20-c-sharp/