png图片更换前景颜色
#region png图片转换前景色
/// <summary>
/// 获取原图的像素点颜色值,修改颜色值
/// </summary>
/// <param name="bmp">原图</param>
/// <returns>修改原图的像素点颜色值之后的图</returns>
public static Bitmap SetBitmapColor(Bitmap bmp, Color bitmapCcolor)
{
int width = bmp.Width;
int height = bmp.Height;
Bitmap newmap = new Bitmap(width, height);
Color pixel;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
pixel = bmp.GetPixel(i, j); // 获取原图的像素点颜色值
int r, g, b, a;
r = pixel.R;
g = pixel.G;
b = pixel.B;
a = pixel.A;
// 判断是否为白色背景
if (r == 255 && g == 255 && b == 255)
{
newmap.SetPixel(i, j, Color.FromArgb(0, 255, 255, 255));
}
else
{
newmap.SetPixel(i, j, Color.FromArgb(255, bitmapCcolor));
}
}
}
//var resultbmp = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat /*?? System.Drawing.Imaging.PixelFormat.Format32bppRgb*/);
//var gr = Graphics.FromImage(resultbmp);
//gr.SmoothingMode = SmoothingMode.AntiAlias;
//gr.CompositingQuality = CompositingQuality.HighQuality;
//gr.CompositingMode = CompositingMode.SourceOver;
//gr.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
//gr.Dispose();
//return resultbmp;
return newmap;
}
/// <summary>
/// 根据Bitmap 对象的跨距宽度(也称为扫描宽度)
/// 单行像素的宽度 = 向上舍入为四字节边界 = ARGB 4个字节
/// (单行像素的宽度,向上舍入为四字节边界。 如果步幅为正数,则位图为自上而下。 如果步幅为负数,则位图为自下而上。
/// </summary>
/// <param name="bitmap">原图</param>
/// <returns>修改原图的像素点颜色值之后的图</returns>
public static Bitmap SetBitmapColor01(Bitmap bmp, Color bitmapCcolor)
{
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
//bmpData.Stride=向上舍入为四字节边界=ARGB4个字节
//获取或设置 Bitmap 对象的跨距宽度(也称为扫描宽度)。
//步幅是扫描线 (单行像素的宽度,向上舍入为四字节边界。 如果步幅为正数,则位图为自上而下。 如果步幅为负数,则位图为自下而上。
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
Marshal.Copy(ptr, rgbValues, 0, bytes);
// Set every third value to 255. A 24bpp bitmap will look red.
//for (int counter = 2; counter < rgbValues.Length; counter += 3)
// rgbValues[counter] = 255;
for (int j = 0; j + 3 < rgbValues.Length; j += 4)
{
// 获取原图的像素点颜色值
int b = rgbValues[j];
int g = rgbValues[j + 1];
int r = rgbValues[j + 2];
int a = rgbValues[j + 3];
// 判断是否为白色背景 png图片背景颜色
if (r == 255 && g == 255 && b == 255)
{
rgbValues[j] = 255;
rgbValues[j + 1] = 255;
rgbValues[j + 2] = 255;
rgbValues[j + 3] = 0;
}
else
{
rgbValues[j] = bitmapCcolor.B;
rgbValues[j + 1] = bitmapCcolor.G;
rgbValues[j + 2] = bitmapCcolor.R;
rgbValues[j + 3] = 255;
}
}
// Copy the RGB values back to the bitmap
Marshal.Copy(rgbValues, 0, ptr, bytes);
// Unlock the bits.
bmp.UnlockBits(bmpData);
Bitmap resultbmp = null;
if (IsIndexedPixelFormat(bmp.PixelFormat))
{
//下面一句 会爆无法从带有索引像素格式的图像创建 Graphics 对象
//var resultbmp = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat);
resultbmp = new Bitmap(bmp.Width, bmp.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
using (var gr = Graphics.FromImage(resultbmp))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.CompositingQuality = CompositingQuality.HighQuality;
gr.CompositingMode = CompositingMode.SourceOver;
gr.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
}
}
else
{
resultbmp = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat);
using (var gr = Graphics.FromImage(resultbmp))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.CompositingQuality = CompositingQuality.HighQuality;
gr.CompositingMode = CompositingMode.SourceOver;
gr.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
}
}
return resultbmp;
}
/// <summary>
/// 获取原图的像素点颜色值,修改颜色值
/// </summary>
/// <param name="bitmap">原图</param>
/// <returns>修改原图的像素点颜色值之后的图</returns>
public static unsafe Bitmap SetBitmapColor02(Bitmap bmp, Color bitmapCcolor)
{
//注意: Marshal.Copy试过操作Format8bppIndexed以及一下的
// Marshal.Copy会出现“//尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”的错误
//解决方法: 先转换成bmp.PixelFormat Format32bppArgb图片
if (IsIndexedPixelFormat(bmp.PixelFormat))
{
bmp = ConvertTo32bpp(bmp);
}
// Lock the bitmap's bits.
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
// Declare an array to hold the bytes of the bitmap.
byte[] rgbValues = new byte[bmp.Width * bmp.Height * 4];
// Copy the RGB values into the array.//注意: Marshal.Copy试过操作Format8bppIndexed以及一下的
// Marshal.Copy会出现“//尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”的错误
//解决方法: 先转换成bmp.PixelFormat Format32bppArgb图片
Marshal.Copy(bmpData.Scan0, rgbValues, 0, rgbValues.Length);
// Set every third value to 255. A 24bpp bitmap will look red.
//for (int counter = 2; counter < rgbValues.Length; counter += 3)
// rgbValues[counter] = 255;
fixed (byte* p = &rgbValues[0])
{
for (int j = 0; j + 3 < rgbValues.Length; j += 4)
{
// 获取原图的像素点颜色值
int b = rgbValues[j];
int g = rgbValues[j + 1];
int r = rgbValues[j + 2];
int a = rgbValues[j + 3];
//var isWhile = bitmapCcolor.R == r && bitmapCcolor.G == r && bitmapCcolor.B == b;
//if (isWhile)
//判断是否为白色背景 png图片背景颜色
if (r == 255 && g == 255 && b == 255)
{
p[j] = 255;
p[j + 1] = 255;
p[j + 2] = 255;
p[j + 3] = 0;
}
else
{
p[j] = bitmapCcolor.B;
p[j + 1] = bitmapCcolor.G;
p[j + 2] = bitmapCcolor.R;
p[j + 3] = 255;
}
}
}
// Copy the RGB values back to the bitmap
Marshal.Copy(rgbValues, 0, bmpData.Scan0, rgbValues.Length);
// Unlock the bits.
bmp.UnlockBits(bmpData);
//var resultbmp = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat /*?? System.Drawing.Imaging.PixelFormat.Format32bppRgb*/);
//var gr = Graphics.FromImage(resultbmp);
//gr.SmoothingMode = SmoothingMode.AntiAlias;
//gr.CompositingQuality = CompositingQuality.HighQuality;
//gr.CompositingMode = CompositingMode.SourceOver;
//gr.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
//gr.Dispose();
Bitmap resultbmp = null;
//resultbmp = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat);
//var gr = Graphics.FromImage(resultbmp);
//gr.SmoothingMode = SmoothingMode.AntiAlias;
//gr.CompositingQuality = CompositingQuality.HighQuality;
//gr.CompositingMode = CompositingMode.SourceOver;
//gr.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
//gr.Dispose();
if (IsIndexedPixelFormat(bmp.PixelFormat))
{
//下面一句 会爆无法从带有索引像素格式的图像创建 Graphics 对象
//var resultbmp = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat);
resultbmp = new Bitmap(bmp.Width, bmp.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
using (var gr = Graphics.FromImage(resultbmp))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.CompositingQuality = CompositingQuality.HighQuality;
gr.CompositingMode = CompositingMode.SourceOver;
gr.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
}
}
else
{
resultbmp = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat);
using (var gr = Graphics.FromImage(resultbmp))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.CompositingQuality = CompositingQuality.HighQuality;
gr.CompositingMode = CompositingMode.SourceOver;
gr.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
}
}
return resultbmp;
}
/// <summary>
/// 判断图片是否索引像素格式,是否是引发异常的像素格式
/// </summary>
/// <param name="imagePixelFormat">图片的像素格式</param>
/// <returns></returns>
public static bool IsIndexedPixelFormat(System.Drawing.Imaging.PixelFormat imagePixelFormat)
{
PixelFormat[] pixelFormatArray = {
PixelFormat.Format1bppIndexed
,PixelFormat.Format4bppIndexed
,PixelFormat.Format8bppIndexed
,PixelFormat.Undefined
,PixelFormat.DontCare
,PixelFormat.Format16bppArgb1555
,PixelFormat.Format16bppGrayScale
};
foreach (PixelFormat pf in pixelFormatArray)
{
if (imagePixelFormat == pf)
{
return true;
}
}
return false;
}
/// <summary>
/// 将图片转为32位的位图
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
public static Bitmap ConvertTo32bpp(Image img)
{
var bmp = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
using (var gr = Graphics.FromImage(bmp))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.CompositingQuality = CompositingQuality.HighQuality;
gr.CompositingMode = CompositingMode.SourceOver;
gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
gr.Dispose();
}
return bmp;
}
#endregion调用方式
//var d = DeviceManager.mxProcessFingerImg("Fingerprint.bmp", "Fingerprint-mxProcessFingerImg.png");
//var bp = Untils.SetBitmapColor(new Bitmap("Fingerprint-mxProcessFingerImg.png"),Color.Red);
//bp.Save("Bitmap2png00.png");
//bp = Untils.SetBitmapColor01(new Bitmap("Fingerprint-mxProcessFingerImg.png"), Color.Red);
//bp.Save("Bitmap2png01.png");
//bp = Untils.SetBitmapColor02(new Bitmap("Fingerprint-mxProcessFingerImg.png"), Color.Red);
//bp.Save("Bitmap2png02.png");
//bp.Dispose();
龙腾一族至尊龙骑
















