the*_*kid 8 c# rgb image image-processing
我目前正在编写一个用Java编写的小程序的C#实现.
我BufferedImage.getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)在我的Java应用程序中使用过函数.但我无法在C#中找到这个版本,我不确定如何手动编写.
And*_*per 18
.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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在可以像这样调用这个包装器:
Bitmap foo = Bitmap.FromFile(@"somefile.jpg") as Bitmap;
int[] rgbArray = new int[100];
foo.getRGB(1, 1, 10, 10, rgbArray, 0, 10);
Run Code Online (Sandbox Code Playgroud)
希望这会有所帮助,并欢迎使用.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);
}
}
Run Code Online (Sandbox Code Playgroud)