【问题标题】:C# fast img mergingC#快速img合并
【发布时间】:2013-12-25 13:32:14
【问题描述】:

今天我想尝试一下 C# 图像处理方面的新东西。

Szenario 如下:我有两张黑白图像。现在我想从两个图像中获取所有白色像素 (x,y) 并将它们放入返回图像中。所以最后我的 image3 包含来自 image1 和 image2 的所有白色像素。 我正在使用不安全的指针,因为它们更快。

所以在代码中,我检查 (x,y) 中的 image1 == (x,y) 中的 image2,因为两张图片不太可能在同一位置有一个白色像素

我现在的做法:

private unsafe static Bitmap combine_img(Bitmap img1, Bitmap img2)
    {
        Bitmap retBitmap = img1;

        int width = img1.Width;
        int height = img1.Height;
        BitmapData image1 = retBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        BitmapData image2 = img2.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // here an error

        byte* scan1 = (byte*)image1.Scan0.ToPointer();
        int stride1 = image1.Stride;

        byte* scan2 = (byte*)image2.Scan0.ToPointer();
        int stride2 = image2.Stride;

        for (int y = 0; y < height; y++)
        {
            byte* row1 = scan1 + (y * stride1);
            byte* row2 = scan2 + (y * stride2);

            for (int x = 0; x < width; x++)
            {
                if (row1[x] == row2[x])
                    row1[x] = 255;
            }
        }

        img1.UnlockBits(image1);
        img2.UnlockBits(image2);

        return retBitmap;
    }

不幸的是,它在尝试锁定第二张图片时返回错误,说该图片已被锁定!

【问题讨论】:

  • 如果您在两个参数上传递相同的图像,那就不足为奇了。即使不是这种情况,您也应该添加验证图像是否相同的代码,以及它们是否正确处理该情况;否则照常继续。
  • 只需交换两个 LockBits 语句。如果它现在抱怨 retBitmap 被锁定,那么它们确实引用了相同的位图数据。如果没有,则将其锁定在其他地方。 UnlockBits() 属于 finally { 块 }。

标签: c# image-processing combiners


【解决方案1】:

问题是,奇怪的是我确实传递了相同的图像,这里是更正的代码:

private unsafe static void combine_img(Bitmap img1, Bitmap img2)
    {
        BitmapData image1 = img1.LockBits(new Rectangle(0, 0, img1.Width, img1.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        BitmapData image2 = img2.LockBits(new Rectangle(0, 0, img2.Width, img2.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        int bytesPerPixel = 3;

        byte* scan1 = (byte*)image1.Scan0.ToPointer();
        int stride1 = image1.Stride;

        byte* scan2 = (byte*)image2.Scan0.ToPointer();
        int stride2 = image2.Stride;

        for (int y = 0; y < img1.Height; y++)
        {
            byte* row1 = scan1 + (y * stride1);
            byte* row2 = scan2 + (y * stride2);

            for (int x = 0; x < img1.Width; x++)
            {
                if (row2[x * bytesPerPixel] == 255)
                    row1[x * bytesPerPixel] = row1[x * bytesPerPixel - 1] = row1[x * bytesPerPixel-2] = 255;
            }
        }
        img1.UnlockBits(image1);
        img2.UnlockBits(image2);
    }

【讨论】:

    【解决方案2】:

    我猜你的第二个图像不是 24 位图像。也许尝试类似:

    BitmapData image2 = img2.LockBits(new Rectangle(0, 0, img2.Width, img2.Height), ImageLockMode.ReadWrite, img2.PixelFormat);
    

    在这种情况下,你总是会通过这条线(我假设),但问题是你不会知道你实际上是在处理 24 位图像还是 32 位图像。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-19
      • 2012-06-27
      • 1970-01-01
      • 2021-07-29
      相关资源
      最近更新 更多