我正在尝试从文件系统加载图像,重新着色,然后将其保存到Stream。有问题的图像是相当简单的单色几何形状。
我有它工作,但结果图像沿边缘重像素化。
我试过System.Drawing:
var colorMap = new ColorMap
{
OldColor = Color.FromArgb(255, 255, 255, 255),
NewColor = Color.FromArgb(255, 255, 0, 0)
};
var imageAttrs = new ImageAttributes();
imageAttrs.SetRemapTable(new[] {colorMap});
var newImage = new Bitmap(image.Width, image.Height);
var graphics = Graphics.FromImage(newImage);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.DrawImage(image,
new Rectangle(0, 0, image.Width, image.Height),
0, 0,
image.Width,
image.Height,
GraphicsUnit.Pixel,
imageAttrs);
我也尝试过使用其ReplaceColor()方法的ImageProcessor库,但我得到了相同的结果(虽然不是很糟糕)。
任何方法都可以保留原始图像的漂亮光滑边缘吗?
答案 0 :(得分:2)
有问题的图像相当简单,单色,几何 形状。
听起来很不错但问题是你的'桌子'颜色太短了,除非图像真的真实地只包含你放入地图的一种颜色!但是这些图像肯定是通过抗锯齿绘制的,因此表中没有涵盖所有抗锯齿像素。你需要
ColorMap
,见下文ColorMatrix
来实现颜色变化。然而,并非所有更改都适合使用它。所以您可能想告诉我们您需要的更改类型.. 你并不孤单:
我刚试过msdn上的example,因为它看起来很错误:保存Jpg
文件不起作用(因为它总会生成自己的颜色表)并且看起来并且看起来它的工作原理,但仅,因为在我的计算机上创建的文件是带有错误扩展名的Png
个文件!将ImageFormat.Jpeg
添加到保存后,它将停止工作..:
原始MSDN代码:
myBitmap.Save("Circle2.jpg");
已更改为
myBitmap.Save("Circle2.jpg", ImageFormat.Jpeg);
结果:
要构建一个合适的ColorMap
,你需要a)遍历所有像素并收集所有不同的颜色(简单但很慢),然后计算目标颜色(快速但不一定简单或明确定义)。
以下两个例程展示了如何构建完整的ColorMap
:
List<Color> GetDistinctColors(Bitmap bmp)
{
List<Color> colors = new List<Color>();
for (int y = 0; y < bmp.Height; y++)
for (int x = 0; x < bmp.Width; x++)
{
Color c = bmp.GetPixel(x,y);
if (!colors.Contains(c)) colors.Add(c);
}
return colors;
}
List<Color> ChangeColors(List<Color> colors)
{
List<Color> newColors = new List<Color>();
foreach(Color c in colors)
{
int A = 255; // here you need..
int R = c.G; // ..to write..
int G = c.R; // ..your custom .
int B = c.B; // ..color change code!!
newColors.Add(Color.FromArgb(A,R,G,B));
}
return newColors;
}
要使用它,请写下:
// prepare the two lists:
List<Color> colors = GetDistinctColors((Bitmap)myImage);
List<Color> newColors = ChangeColors(colors);
// Create a complete color map
ColorMap[] myColorMap = new ColorMap[colors.Count];
for (int i = 0; i < colors.Count; i++)
{
myColorMap[i] = new ColorMap();
myColorMap[i].OldColor = colors[i];
myColorMap[i].NewColor = newColors[i];
}
请注意,为ChangeColor函数编写正确的代码并不简单。您不仅需要知道自己想要什么,还需要正确的工具来实现它。在上面的代码示例中,我做了一个非常简单的通道交换。这通常不会产生您想要的结果:素色和消除锯齿的像素都不能如此简单地改变。相反,你应该从RGB转换为HSL或HSV,并在那里改变色调!请参阅此处查看SetHue example!