试图理解这个图像功能

时间:2013-12-06 17:35:39

标签: c# arrays unsafe

private void ReadImage()
    {
        int i, j;
        GreyImage = new int[Width, Height];  //[Row,Column]
        Bitmap image = Obj;
        BitmapData bitmapData1 = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
                                 ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        unsafe
        {
            byte* imagePointer1 = (byte*)bitmapData1.Scan0;

            for (i = 0; i < bitmapData1.Height; i++)
            {
                for (j = 0; j < bitmapData1.Width; j++)
                {
                    GreyImage[j, i] = (int)((imagePointer1[0] + imagePointer1[1] + imagePointer1[2]) / 3.0);
                    //4 bytes per pixel
                    imagePointer1 += 4;
                }//end for j
                //4 bytes per pixel
                imagePointer1 += bitmapData1.Stride - (bitmapData1.Width * 4);
            }//end for i
        }//end unsafe
        image.UnlockBits(bitmapData1);
        return;
    }

线GreyImage[j,i] = (int)((imagePointer1[0] .....似乎正在像数组一样读入byte*,显然我不能将一个不安全的代码分配给一个数组以供以后处理,所以我想也许只是分配那些4个字节到数组。

如何将这4个字节分配给数组?

我想这样做:

var imageData = new byte[Width, Height][];
imageData[x,y] = pixelSet //basically byte[];

任何想法

2 个答案:

答案 0 :(得分:1)

我认为你正在尝试做这样的事情。显然,我没有测试过这段代码,但它会让你朝着你想要的方向前进。

byte[] save = new byte[4];
Array.Copy(*imagePointer1, save, 4);

OR

byte[] save = new byte[4];
save[0] = bitmapData1.Scan0[0];
save[1] = *(imagePointer1 + 1);
save[2] = *(imagePointer1 + 2);
save[3] = *(imagePointer1 + 3);

指向数组的指针始终指向元素零。您可以通过添加指针或递增指针来访问其他元素。

 (imagePointer1 + 5)  // pointer to 5th element
*(imagePointer1 + 5)  // value of 5th element
  imagePointer1 += 5; // imagePointer1 now starts at element 5

加号和减号将指针引用移动到构成数组数据类型大小的字节数。如果它是一个int [],+和 - 将以4个字节的增量移动指针。

我希望这会帮助你。

答案 1 :(得分:0)

该函数应将图像转换为灰度图像,并将颜色值存储到GreyScale数组中。但是这个函数有一个错误(实际上是2)。

首先,你只阅读图像的左上角像素,而不应该使用它:

GreyImage[j, i] = (int)((imagePointer1[j * 4 + i * bitmapData1.Width * 4] + imagePointer1[j * 4 + i * bitmapData1.Width * 4 + 1] + imagePointer1[j * 4 + i * bitmapData1.Width * 4 + 2]) / 3.0);

另一件事是,当您转换图像时,所有颜色都不是“相等”,您可以在谷歌上找到应用于红色,绿色和蓝色通道的常用因子,以便在Google上轻松转换为灰度。

要回答你的问题,你在函数中为数组赋值的方式是正确的。

修改

回答你的意见:

在方括号[]中,我计算数组中坐标(j, i)处像素颜色信息的偏移量。 (顺便说一句,我们通常i使用xj使用y,这里恰恰相反)

假设您想知道坐标x = 2, y = 4处像素的颜色值,则需要使用以下公式:

color = y * <number of bytes per line> + x

由于您的图像是32位,使用上面的公式,您将获得颜色的红色值。 如果你想要绿色的那个你加1,对于蓝色你加2。

在我发布的代码中,我假设每一行都采用width * 4个字节,大多数时候32位图像都是如此,但并非总是如此,所以最好实际使用这个公式: / p>

[imagePointer[i * bitmapData1.Stride + j]