【问题标题】:Efficient way to replace specific color in Bitmap/Image替换位图/图像中特定颜色的有效方法
【发布时间】:2013-03-01 10:49:31
【问题描述】:

在我的灰度图片中,我需要找到特定的值并将其替换为某种颜色,例如黄色。这是我现在拥有的代码,但它没有我需要的那么快。有没有更有效的方法来实现这一目标?我对 ColorMatrix 类感到不满,但找不到在不影响整个图像的情况下替换单个值的方法。

unsafe
{
    byte stlThres = 115;

    int bytePerPixel = Image.GetPixelFormatSize(kpImageViewer1.Image.PixelFormat) / 8;
    var data = kpImageViewer1.Image.LockBits(new Rectangle(0, 0, kpImageViewer1.Image.Width, kpImageViewer1.Image.Height), ImageLockMode.WriteOnly, kpImageViewer1.Image.PixelFormat);
    for (int y = 0; y < data.Height; y++)
    {
        byte* row = (byte*)data.Scan0 + (y * data.Stride);

        for (int x = 0; x < data.Width; x++, row += bytePerPixel)
        {
            if (row[0] == stlThres)
            {
                row[0] = 0; //b
                row[1] = 255; //g
                row[2] = 255; //r
                if (bytePerPixel == 4)
                {
                    row[3] = 255; //a
                }
            }
        }
    }
    kpImageViewer1.Image.UnlockBits(data);
}

【问题讨论】:

  • 你可以试试 BitBlt。 Here's VB 示例。
  • 非常小的调整可能会将您的data.Scan0data.Widthdata.StrideBytePerPixel == 4 完全移到循环之外,因为它们在循环期间是有效的常量(最后一个意味着你必须复制基本的循环结构)。它可能会提供轻微的(但可能是可衡量的改进,具体取决于调用频率和位图的大小)
  • 添加您的结果和实际结果的图像

标签: c# .net image image-processing bitmap


【解决方案1】:

对于 4 通道图像,其中每个像素为 4 字节(每个通道 8 位),您可以使用由 row[0] 索引的 256 条目查找表,并将所有四个通道同时分配为单个 32 -位int

【讨论】:

  • 好点,但 4 通道图像是一种非常罕见的情况,我添加此检查只是为了兼容性。所以我现在缺少 Int24 类型:D
  • 在 3 通道图像的情况下,您可能会尝试同时处理 4 个像素,并使用一些位掩码将它们视为 3 ints。
  • 你能举个例子吗?
  • 我不确定这是否真的值得。只需移除环路外的 4 通道测试并保持环路紧密。
猜你喜欢
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-11
  • 1970-01-01
  • 2016-04-02
  • 2018-01-19
相关资源
最近更新 更多