首页 > 其他分享 >png图片更换前景颜色

png图片更换前景颜色

时间:2024-04-29 18:45:45浏览次数:20  
标签:gr rgbValues PixelFormat Bitmap bmp new 更换 前景 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();

 

标签:gr,rgbValues,PixelFormat,Bitmap,bmp,new,更换,前景,png
From: https://www.cnblogs.com/1175429393wljblog/p/18166481

相关文章

  • Dell R720 内存纠错比率超限 更换内存引起的故障
    DellR720内存纠错比率超限更换内存引起的故障2019年12月18日 8823点热度 27人点赞 0条评论0x01前言服务器里有一根内存出现异常,在除错的过程中我详细了解R720的内存配置。我在这里将除错过程和基本配置信息记录下来。0x02错误在上周,我发现服务器后部的状态灯不再......
  • 小程序图片缓存策略(不改代码更换OSS图片)
    昨天,后端给我提了一个问题:他更换了CDN上的图片,但是他打开小程序来看,还是旧图片,他尝试过删除小程序,重新进,还是旧图片。我第一反应是:“你有没有清CDN缓存?“他说:”我在阿里云CDN控制台刷新缓存了,都两三天了,还是旧图片。”(后来我看过刷缓存记录,一天前刚刷的,他夸张了。。。)我说:“那......
  • pycharm更换编辑器默认编码方式
    Pycharm运行py文件,出现SyntaxError:Non-UTF-8codestartingwith'\xb5'infileF:\桌面\python\tk_learning\01.pyonline7,butnoencodingdeclared;seehttps://python.org/dev/peps/pep-0263/fordetails错误这个错误通常意味着你的Python源代码文件中包含了非UTF......
  • kali 设置 Java 版本,并更换为 1.8 版本
    kali设置Java版本,并更换为1.8版本1.安装JDK1.下载java1.8:https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz2.建立目录,将下载的jdk的安装包复制过去并进行解压sudomkdir-p/usr/local/javacpjdk-8u202-linux-x64.tar.gz/usr/l......
  • kali 更换国内源
    kali更换国内源vim/etc/apt/sources.list国内源#中科大debhttp://mirrors.ustc.edu.cn/kalikali-rollingmainnon-freecontribdeb-srchttp://mirrors.ustc.edu.cn/kalikali-rollingmainnon-freecontrib#阿里云debhttp://mirrors.aliyun.com/kalikali-rolling......
  • 探索人工智能在测试领域的新纪元:AI编写测试用例的前景
    简介测试用例是测试人员的核心工作内容,是测试人员思想的“实现类”,其充分体现了测试的思路,可以为后续的测试行为提供指导,是测试人员了解业务的重要根据和质量之根本。如果测试用例设计得不完成,出现了遗漏,那么通常是会出现大家不想看到的后果,如漏测、线上Bug不断等。——引用自......
  • 简述:将带透明通道的PNG图片叠加到Framebuf上
    PNG图片,维基百科简介:https://zh.wikipedia.org/wiki/PNG现在带透明通道的最常见的PNG文件都是PNG32格式,所以首先将PNG文件解析为RGBA-8-8-8-8即32位真彩像素(PNG32)(A代表Alpha透明通道)PNG帧解析PNG文件编码比BMP复杂一点,但还是可以解析的。在no_stdrust上我就偷懒使用了mi......
  • 【布客技术评论】大模型开源与闭源:原因、现状与前景
    在人工智能领域,大模型的开源与闭源一直是一个备受争议的话题。近期,某大厂厂长说了“开源模型永远超不过闭源模型”,结果,脸书就发布了开源必须Llama,超过了OpenAI的闭源模型GPT4。本文将探讨大模型开源与闭源的原因、当前状况以及未来前景,以期为读者提供深入的理解和分析。算力稀......
  • BOSHIDA DC电源模块的发展趋势和前景展望
    BOSHIDADC电源模块的发展趋势和前景展望随着电子产品的普及和多样化,对电源模块的需求也越来越大。其中,DC电源模块作为一种重要的电源供应方式,在各个领域有着广泛的应用。在过去的几十年里,DC电源模块已经经历了多次技术革新和发展,未来的发展趋势也值得关注。本文将从多个方面对DC......
  • Ubuntu部署有道QAnything(中间涉及到更换mysql容器端口)
    1、系统配置版本:Ubuntu20.04有两块3090的显卡2、下载相关文件首先下载源码,下载完成后解压得到QAnything-master文件夹github下载地址:https://github.com/netease-youdao/qanythinggitee下载地址:https://gitee.com/netease-youdao/QAnything?_from=gitee_search下载embed......