c# - FillRectangle 未使用提供的 SolidBrush 的精确颜色进行填充

标签 c# .net

我正在用颜色填充位图:

// Assume we have something like: 
// Bitmap bitmap = new Bitmap(3, 2, PixelFormat.Format32bppArgb);

using (SolidBrush b = new SolidBrush(color))
{
    using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(Bitmap))
    {
        g.FillRectangle(b, 0, 0, Bitmap.Width, Bitmap.Height);
    }
}

但是,当我执行诸如 Bitmap.GetPixel(0, 0) 之类的操作时,它将返回一个 Color ,该颜色接近但不相同 -我把它放在刷子里。如果我将 Color 上的 alpha channel 降得足够低,则 RGB 颜色 channel 将为零。例如,Color.FromArgb(1, 2, 3, 4) 作为画笔颜色将生成一个充满 1, 0, 0, 0 的位图。如果我执行 Color.FromArgb(11, 22, 33, 44) ,那么我会得到一个颜色类似于 11, 22, 22, 44 的位图。因此,我的单元测试正在崩溃。因为我无法获得直接匹配。

有没有办法让我用我提供的精确纯色快速填充整个矩形?速度很重要,这在程序中有点热循环中,因此不可能执行 Bitmap.SetPixel(...) 。除非没有其他办法,否则我宁愿不做不安全

<小时/>
using System;
using System.Drawing;
using System.Drawing.Imaging;

public class Program
{
    public static void Main()
    {
        Bitmap Bitmap = new Bitmap(3, 2, PixelFormat.Format32bppArgb);

        using (SolidBrush b = new SolidBrush(Color.FromArgb(1, 2, 3, 4)))
        {
            using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(Bitmap))
            {
                g.FillRectangle(b, 0, 0, Bitmap.Width, Bitmap.Height);
            }
        }

        var pixel = Bitmap.GetPixel(0, 0);
        Console.WriteLine(pixel);
    }
}

最佳答案

使用LockBits()并设置内存中的颜色:

public static Bitmap Fill(Bitmap bmp, Color color)
{
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    System.Drawing.Imaging.BitmapData bmpData =
        bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
        bmp.PixelFormat);
    IntPtr ptr = bmpData.Scan0;
    int bytes  = Math.Abs(bmpData.Stride) * bmp.Height;
    byte[] rgbValues = new byte[bytes];
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);  
    for (int i= 0; i< rgbValues.Length; i+= 4)
    {
         rgbValues[i] = color.A;
         rgbValues[i] = color.B;
         rgbValues[i] = color.G;
         rgbValues[i] = color.R;
    }
    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
    bmp.UnlockBits(bmpData);
    e.Graphics.DrawImage(bmp, 0, 0);
    return bmp;
}

关于c# - FillRectangle 未使用提供的 SolidBrush 的精确颜色进行填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59381555/

相关文章:

c# - Nodatime 计算 X 天内的年/月/日

c# - Asp.Net Mvc 在来自临时数据的 View 中显示异常

c# - 如何从多维数组中获取维度(切片)

c# - 重命名显示 List<T> 的 DataGridView 的列的最简单方法是什么?

使用通配符证书通过 SSL 的 C# Web 服务调用 (asmx)

c# - 跨多个折线图的垂直线,并在 Winforms 中显示每个图表的值

c# - 需要一些关于尝试模拟 .NET WebClient 或等效物的建议

c# - 在 C# TimeSpan 类中循环一周中的几天

c# - 如何将 X509SigningCredentials 与 System.IdentityModel.Tokens.Jwt.JwtHeader 一起使用?

c# - 我可以将 WPF 控件绑定(bind)到字段的属性吗?