不安全的代码说明

时间:2016-07-05 18:36:19

标签: c#-4.0 bitmap unsafe bitmapdata

        private static Complex[,] FromBitmapData(BitmapData _BitmapData)
        {
            if (_BitmapData.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                throw new Exception("Source can be grayscale (8bpp indexed) only.");
            }

            int width = _BitmapData.Width;
            int height = _BitmapData.Height;
            int offset = _BitmapData.Stride - width;

            if ((!Utils.IsPowerOf2(width)) || (!Utils.IsPowerOf2(height)))
            {
                throw new Exception("Image width and height should be power of 2.");
            }

            Complex[,] data = new Complex[width, height];

            unsafe
            {
                byte* src = (byte*)_BitmapData.Scan0.ToPointer();

                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++, src++)
                    {
                        data[y, x] = new Complex((float)*src / 255, 
                                                    data[y, x].Imaginary);
                    }

                    src += offset;
                }
            }

            return data;
        }

为什么*src指向的值除以255?

1 个答案:

答案 0 :(得分:0)

什么是Stride

对于像对齐等目的,有时位图中的像素行比宽度长 - 而它的长度称为步幅。因此,您可以使用width = 3和stride = 4,并且数据行将如下所示:

Row: [Pixel][Pixel][Pixel][Unused]

offset代表什么?

这是步幅和宽度之间的差异,即当您已经读取了一行中的所有实际像素时,为了到达下一行,您需要跳过多少未使用的像素。

为什么src在内循环中递增1,并且在外循环中又递增offset

内部循环读取行的像素,因此src递增1以在每次迭代中到达下一个像素。但是在你全部阅读之后,你需要跳过offset未使用的数据才能进入下一行。

为什么*src指向的值除以255

复杂类型具有浮点组件,8bpp位图中的像素由字节表示,因此它们具有0–255的值。除以255将它们转换为范围0.0–1.0中的浮点数。

为什么data[x,y].Imaginary作为参数传递?

由于某种原因,此函数以复杂类型存储位图数据,而复杂类型具有实部和虚部,因此分配

data[y, x] = new Complex(something, data[y,x].Imaginary); 

表示:将data[y,x]的实部分设置为某个部分并保留虚部。