图像几何运算 平移,镜像,缩放

图像的平移

  private void translationBtn_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                //实例化translation窗口体
                translation traForm = new translation();

                if (traForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect,
                        System.Drawing.Imaging.ImageLockMode.ReadWrite,
                        curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = bmpData.Stride * curBitmap.Height;//图像的跨度curBitmap.Width并不一定是其实际像素宽度
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    //得到两个方向的图像平移量
                    int x = Convert.ToInt32(traForm.GetXOffset);
                    int y = Convert.ToInt32(traForm.GetYOffset);


                    byte[] tempArray = new byte[bytes];
                    //临时数组初始化为白色像素

                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = 255;
                    }

                    //平移运算
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        //保证纵向平移不出界
                        if ( (i + y) < curBitmap.Height && (i + y) > 0 ) 
                        {
                            for (int j = 0; j < bmpData.Stride; j++)
                            {
                                //保证横向不出界
                                if ((j + x) < bmpData.Stride && (j + x) > 0)
                                {
                                    //应用公式
                                    tempArray[(j + x) + (i + y) * bmpData.Stride] =
                                        grayValues[j + i * bmpData.Stride];
                                }
                            }
                        }

                    }
                    //数组复制,返回平移后的图像
                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

//图像镜像变换

 private void mirrorBtn_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                //实例化mirror窗口体
                Mirror mirForm = new Mirror();

                if (mirForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect,
                        System.Drawing.Imaging.ImageLockMode.ReadWrite,
                        curBitmap.PixelFormat);

                    IntPtr ptr = bmpData.Scan0;
                    int bytes = bmpData.Stride * bmpData.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    //水平中轴
                    int halfWidth = bmpData.Stride / 2;
                    //垂直中轴
                    int halfHeight = curBitmap.Height / 2;
                    byte temp;

                    if (mirForm.GetMirror)
                    {
                        //水平镜像处理
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            for (int j = 0; j < halfWidth; j++)
                            {
                                //以水平中轴为对称轴, 两边的像素值互换
                                temp = grayValues[i * bmpData.Stride + j];
                                grayValues[i * bmpData.Stride + j] =
                                    grayValues[(i + 1) * bmpData.Stride - j - 1];
                                grayValues[(i + 1) * bmpData.Stride - 1 - j] = temp;
                            }

                        }
                    }
                    else
                    {
                        //垂直镜像处理
                        for (int i = 0; i < bmpData.Stride; i++)
                        {
                            for (int j = 0; j < halfHeight; j++)
                            {
                                //以垂直中轴为对称轴, 两边的像素值互换
                                temp = grayValues[j * bmpData.Stride + i];
                                grayValues[j * bmpData.Stride + i] =
                                    grayValues[(curBitmap.Height - j - 1) * bmpData.Stride + i];
                                grayValues[(curBitmap.Height - j - 1) * bmpData.Stride + i] =
                                    temp;

                            }

                        }
                    }
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

//图像缩放

private void zoomBtn_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                //实例化zoom窗口
                zoom zoomForm = new zoom();

                if (zoomForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpdata = curBitmap.LockBits(rect,
                        System.Drawing.Imaging.ImageLockMode.ReadWrite,
                        curBitmap.PixelFormat);
                    IntPtr ptr = bmpdata.Scan0;
                    int bytes = bmpdata.Stride * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    //得到横纵缩放量
                    double x = Convert.ToDouble(zoomForm.GetXZoom);
                    double y = Convert.ToDouble(zoomForm.GetYZoom);

                    //图像的几何中心
                    int halfWidth = (int)Convert.ToDouble(bmpdata.Stride / 2);
                    int halfHeight = (int)Convert.ToDouble(curBitmap.Height / 2);

                    int xz = 0;
                    int yz = 0;
                    int tempWidth = 0;
                    int tempHeight = 0;
                    byte[] tempArray = new byte[bytes];

                    if (zoomForm.GetNearOrBil == true)
                    {
                        //最近邻插值法
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            for (int j = 0; j < bmpdata.Stride; j++)
                            {
                                //以图像的几何中心为坐标原点进行坐标变化
                                //按逆向映射法得到输入图像坐标
                                tempHeight = i - halfHeight;
                                tempWidth = j - halfWidth;

                                //在不同象限里进行四舍五入处理,得到缩放后像素点到中心点的距离
                                if (tempWidth > 0)
                                {
                                    xz = (int)(tempWidth / x + 0.5);
                                }
                                else
                                {
                                    xz = (int)(tempWidth / x - 0.5);
                                }

                                if (tempHeight > 0)
                                {
                                    yz = (int)(tempHeight / y + 0.5);
                                }
                                else
                                {
                                    yz = (int)(tempHeight / y - 0.5);
                                }

                                //坐标变换,得到缩放后像素的位置
                                tempWidth = xz + halfWidth;
                                tempHeight = yz + halfHeight;
                                //得到输出图像像素值
                                if (tempWidth < 0 || tempWidth >= bmpdata.Stride ||
                                    tempHeight < 0 || tempHeight >= curBitmap.Height)
                                {
                                    //缩放后留下的空白部分用白色像素代替
                                    tempArray[i * bmpdata.Stride + j] = 255;
                                }
                                else
                                {
                                    tempArray[i * bmpdata.Stride + j] =
                                        grayValues[tempHeight * bmpdata.Stride + tempWidth];
                                }
                            }
                        }
                    }
                    else
                    {
                        //双线性插值法
                        double tempX, tempY, p, q;
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            for (int j = 0; j < bmpdata.Stride; j++)
                            {
                                //以图像的几何中心为坐标原点进行坐标变化
                                //按逆向映射法的到输入图像的坐标
                                tempHeight = i - halfHeight;
                                tempWidth = j - halfWidth;
                                tempX = tempWidth / x;
                                tempY = tempHeight / y;

                                //在不同象限进行取整处理
                                if (tempWidth > 0)
                                {
                                    xz = (int)tempX;
                                }
                                else
                                {
                                    xz = (int)(tempX - 1);
                                }
                                if (tempHeight > 0)
                                {
                                    yz = (int)tempY;
                                }
                                else
                                {
                                    yz = (int)(tempY - 1);
                                }

                                //得到公式中的变量p和q
                                p = tempX - xz;
                                q = tempY - yz;

                                //坐标变换
                                tempWidth = xz + halfWidth;
                                tempHeight = yz + halfHeight;

                                if (tempWidth < 0 || (tempWidth + 1) >= bmpdata.Stride ||
                                    tempHeight < 0 || (tempHeight + 1) >= curBitmap.Height)
                                {
                                    //缩放后留下的空白部分用白色像素代替
                                    tempArray[i * bmpdata.Stride + j] = 255;
                                }
                                else
                                {
                                    //应用公式得到双线性插值
                                    tempArray[i * bmpdata.Stride + j] =
                                        (byte)(
                                                (1.0 - q) * (
                                                              (1.0 - p) * grayValues[tempHeight * bmpdata.Stride + tempWidth]
                                                               +
                                                               p * grayValues[tempHeight * bmpdata.Stride + tempWidth + 1]
                                                             )
                                                  +
                                                 q *
                                                 (
                                                   (1.0 - q) * grayValues[(tempHeight + 1) * bmpdata.Stride + tempWidth]
                                                   +
                                                   p * grayValues[(tempHeight + 1) * bmpdata.Stride + 1 + tempWidth]
                                                 )
                                             );
                                }
                            }
                        }

                    }

                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpdata);
                   
                }

                Invalidate();
            }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值