指针法处理图像

1.指针法基类

class PointBitmap
    {
        Bitmap source = null;//数据源
        IntPtr Iptr = IntPtr.Zero;
        BitmapData bitmapData = null;
        public int Depth { get; private set; }
        public int Width { get; private set; }
        public int Height { get; private set; }
        public PointBitmap(Bitmap source)
        {
            this.source = source;
        }
        public void LockBits()
        {
            try
            {
                // 从source获取位图的宽度和高度
                Width = source.Width;
                Height = source.Height;

                // 获取总锁定像素数数量
                int PixelCount = Width * Height;

                // 创建要锁定的矩形,也就是生成图片的大小
                Rectangle rect = new Rectangle(0, 0, Width, Height);

                // 获取源位图像素格式大小、8、24、32
                Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);

                // 检查bpp(每像素位数)是否为8、24或32,不符合则输出提示
                if (Depth != 8 && Depth != 24 && Depth != 32)
                {
                    throw new ArgumentException("仅支持8、24和32个bpp映像。");
                }

                // 锁定位图并返回位图数据
                bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);

                //得到首地址
                unsafe
                {
                    Iptr = bitmapData.Scan0;
                    //二维图像循环
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public void UnlockBits()
        {
            try
            {
                source.UnlockBits(bitmapData);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public Color GetPixel(int x, int y)
        {
            unsafe
            {
                byte* ptr = (byte*)Iptr;
                ptr = ptr + bitmapData.Stride * y;
                ptr += Depth * x / 8;
                Color c = Color.Empty;
                if (Depth == 32)
                {
                    int a = ptr[3];
                    int r = ptr[2];
                    int g = ptr[1];
                    int b = ptr[0];
                    c = Color.FromArgb(a, r, g, b);
                }
                else if (Depth == 24)
                {
                    int r = ptr[2];
                    int g = ptr[1];
                    int b = ptr[0];
                    c = Color.FromArgb(r, g, b);
                }
                else if (Depth == 8)
                {
                    int r = ptr[0];
                    c = Color.FromArgb(r, r, r);
                }
                return c;
            }
        }
        public void SetPixel(int x, int y, Color c)
        {
            unsafe
            {
                byte* ptr = (byte*)Iptr;
                ptr = ptr + bitmapData.Stride * y;
                ptr += Depth * x / 8;
                if (Depth == 32)
                {
                    ptr[3] = c.A;
                    ptr[2] = c.R;
                    ptr[1] = c.G;
                    ptr[0] = c.B;
                }
                else if (Depth == 24)
                {
                    ptr[2] = c.R;
                    ptr[1] = c.G;
                    ptr[0] = c.B;
                }
                else if (Depth == 8)
                {
                    ptr[2] = c.R;
                    ptr[1] = c.G;
                    ptr[0] = c.B;
                }
            }
        }
    }

2.写调用基类的图像处理函数

/// <summary>
        /// byte[] To BitmapImage
        /// </summary>
        /// <param name="sd">sd图像数据格式 一个byte[]对应1个像素点 </param>
        /// <param name="bmp">new的Bitmap对象</param>
        /// <returns>BitmapImage</returns>
        public static BitmapImage CommondRgb(byte[] sd, Bitmap bmp)
        {
            int index = 0;
            Color color = Color.FromArgb(1);
            PointBitmap point_bmp = new PointBitmap(bmp);
            point_bmp.LockBits();
            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    //收到的数据为12 34 56 78  四个为1个像素点
                        //            R  G  B  A
                        color = Color.FromArgb(sd[index], sd[index], sd[index]);//ARGB,这里A为默认值255
                        point_bmp.SetPixel(x, y, color);
                        index++;
                    
                }
            }
            point_bmp.UnlockBits();
            return bitmapImageFill;
        }

代码中 index++目前为8位图像处理的算法,

若为24位图像,则为index+=3,

Color.FromArgb(sd[index+2], sd[index+1], sd[index]);

若为32位图像,index+=4。
Color.FromArgb(sd[index+3],sd[index+2], sd[index+1], sd[index]);

3.运用函数画图

Bitmap bmp = new Bitmap(w, h);
tpImage.Source = ImageHelper.CommondRgb(temp, bmp);

w, h为图像的宽高;temp为字节数组;

比如:宽高的为5的图像按照现有算法处理,byte[] temp = new byte[25]; 数组长度为25,8位图像,可理解为每个字节数组对应一个像素点。

 

posted @ 2022-07-28 15:32  驼七  阅读(35)  评论(0)    收藏  举报