png图片更换前景颜色
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();
龙腾一族至尊龙骑
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义