在C#中从图像获取RGB数组
c#
image
image-processing
6
0

我目前正在编写一个用Java编写的小程序的C#实现。

我在Java应用程序中使用了BufferedImage.getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)函数。但是我无法在C#中找到该版本,也不确定如何手动编写。

参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

我认为最接近的是Bitmap.GetPixel(x,y) ,它在某个点返回单个像素的颜色。为了模拟Java函数,您将需要编写一些帮助器。

收藏
评论

.NET Framework中没有与此方法直接等效的方法。但是,如果图像是System.Drawing.Bitmap,则可以调用LockBits方法,这将返回一个BitmapData结构,该结构包含第一条扫描线的地址。然后,您可以使用它来创建应该是与API兼容的包装器。我假设您使用的是C#3.5或更高版本,所以我使用的是扩展方法-如果您使用的是较旧的样式,请通过从Bitmap参数中删除“ this”将其更改为常规方法:

    public static void getRGB(this Bitmap image, int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)
    {
        const int PixelWidth = 3;
        const PixelFormat PixelFormat = PixelFormat.Format24bppRgb;

        // En garde!
        if (image == null) throw new ArgumentNullException("image");
        if (rgbArray == null) throw new ArgumentNullException("rgbArray");
        if (startX < 0 || startX + w > image.Width) throw new ArgumentOutOfRangeException("startX");
        if (startY < 0 || startY + h > image.Height) throw new ArgumentOutOfRangeException("startY");
        if (w < 0 || w > scansize || w > image.Width) throw new ArgumentOutOfRangeException("w");
        if (h < 0 || (rgbArray.Length < offset + h * scansize) || h > image.Height) throw new ArgumentOutOfRangeException("h");

        BitmapData data = image.LockBits(new Rectangle(startX, startY, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat);
        try
        {
            byte[] pixelData = new Byte[data.Stride];
            for (int scanline = 0; scanline < data.Height; scanline++)
            {
                Marshal.Copy(data.Scan0 + (scanline * data.Stride), pixelData, 0, data.Stride);
                for (int pixeloffset = 0; pixeloffset < data.Width; pixeloffset++)
                {
                    // PixelFormat.Format32bppRgb means the data is stored
                    // in memory as BGR. We want RGB, so we must do some 
                    // bit-shuffling.
                    rgbArray[offset + (scanline * scansize) + pixeloffset] = 
                        (pixelData[pixeloffset * PixelWidth + 2] << 16) +   // R 
                        (pixelData[pixeloffset * PixelWidth + 1] << 8) +    // G
                        pixelData[pixeloffset * PixelWidth];                // B
                }
            }
        }
        finally
        {
            image.UnlockBits(data);
        }
    }

现在可以这样调用该包装器:

        Bitmap foo = Bitmap.FromFile(@"somefile.jpg") as Bitmap;
        int[] rgbArray = new int[100];
        foo.getRGB(1, 1, 10, 10, rgbArray, 0, 10);

希望对您有所帮助,并欢迎使用.NET!

收藏
评论

您将使用Bitmap.LockBits直接访问位图中的像素。这是一个示例实现,它从传递的位图中以int []的形式返回一条扫描线:

    int[] getRGB(Bitmap bmp, int line) {
        var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
            System.Drawing.Imaging.ImageLockMode.ReadOnly,
            System.Drawing.Imaging.PixelFormat.Format32bppRgb);
        try {
            var ptr = (IntPtr)((long)data.Scan0 + data.Stride * (bmp.Height - line - 1));
            var ret = new int[bmp.Width];
            System.Runtime.InteropServices.Marshal.Copy(ptr, ret, 0, ret.Length * 4);
            return ret;
        }
        finally {
            bmp.UnlockBits(data);
        }
    }
收藏
评论
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号