场景:有时,我们需要给透明Png黑白图片改变成指定颜色(上色)。
前提:我们已经做好了带透明通道的PNG图片。
益处:使用此方法,只需要制作一张透明的黑色PNG图片即可,我们需要不同颜色的同样式图片时,直接使用本程序LOAD一个。
话不多说,直接上代码:
public static Bitmap ChangePngColor(string pngFileName, Color destColor)
{
Bitmap curBitmap = (Bitmap)Image.FromFile(pngFileName);
if (curBitmap != null)
{
Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
int c = curBitmap.PixelFormat == PixelFormat.Format32bppArgb ? 4 : 3;
IntPtr ptr = bmpData.Scan0;
int numBytes = bmpData.Stride * curBitmap.Height;
byte[] rgbValues = new byte[numBytes];
Marshal.Copy(ptr, rgbValues, 0, numBytes);
for (int counter = 0; counter < rgbValues.Length; counter += c)
{
if (c == 3)
{
if (rgbValues[counter] != destColor.R &&
rgbValues[counter + 1] != destColor.G &&
rgbValues[counter + 2] != destColor.B)
{
rgbValues[counter] = destColor.R;
rgbValues[counter + 1] = destColor.G;
rgbValues[counter + 2] = destColor.B;
}
}
else if (c == 4)
{
if (rgbValues[counter + 3] > 128 && rgbValues[counter] < 20)
{
rgbValues[counter] = destColor.B;
rgbValues[counter + 1] = destColor.G;
rgbValues[counter + 2] = destColor.R;
rgbValues[counter + 3] = destColor.A;
}
}
}
Marshal.Copy(rgbValues, 0, ptr, numBytes);
curBitmap.UnlockBits(bmpData);
}
return curBitmap;
}
调用方法:
private void menuItemPngToColorImage_Click(object sender, EventArgs e)
{
Color destColor = Color.FromArgb(255, Color.Red);
string pngFileName = @"XXX.png";
Bitmap curBitmap = ChangePngColor(pngFileName, destColor);
using (Graphics gg = this.CreateGraphics())
{
gg.Clear(Color.White);
gg.SmoothingMode = SmoothingMode.HighQuality;
gg.DrawImage(curBitmap, 0, 0, curBitmap.Width, curBitmap.Height);
}
}
原图:
改变颜色后的图片:
注意:为了加快速度,需要允许不安全代码。
另:
也可以采用类似如下代码:
public static Bitmap ReplaceColor(string photoFileName, Color oldColor, Color newColor)
{
Bitmap result=new Bitmap(1,1);
using (Bitmap bmp = new Bitmap(@photoFileName))
{
result=new Bitmap(bmp.Width,bmp.Height);
Graphics g = Graphics.FromImage(result);
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
ColorMap[] colorMap = new ColorMap[1];
colorMap[0] = new ColorMap();
colorMap[0].OldColor = oldColor;
colorMap[0].NewColor = newColor;
ImageAttributes attr = new ImageAttributes();
attr.SetRemapTable(colorMap);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
g.DrawImage(bmp, rect, 0, 0, rect.Width, rect.Height, g.PageUnit, attr);
}
return result;
}