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();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章