C#图像处理初学之平移和镜像

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

//出现图像的不完全处理的原因是我们打开的24为bmp图像而不是书上说的8为bmp图像
//因此图像的像素点是height*width*3

namespace Transfer
{
    public partial class Form1 : Form
    {
        private string curFileName;
        private System.Drawing.Bitmap curBitmap;
        public Form1()
        {
            InitializeComponent();
        }

        private void open_Click(object sender, EventArgs e)
        {
            OpenFileDialog opnDlg = new OpenFileDialog();
            //为图像选择一个筛选器
            opnDlg.Filter = "所有图像文件|*.bmp;*.pcx;*.png;*.jpg;*.gif;*.tif;*.ico;*.dxf;*.cgm;*.cdr;*.wmf;*.eps;*.emf|" +
                "位图(*.bmp;*.jpg;*.png;...)|*.bmp;*.pcx;*.png;*.jpg;*.gif;*.tif;*.ico|" +
                "矢量图(*.wmf;*.eps;*.emf;...)|*.dxf;*.cgm;*.cdr;*.wmf;*.eps;*.emf";
            //设置对话框标题
            opnDlg.Title = "打开图像文件";
            //启用“帮助”功能
            opnDlg.ShowHelp = true;
            //如果结果为“打开”,选定文件
            if (opnDlg.ShowDialog() == DialogResult.OK)
            {
                //读取当前选中的文件名
                curFileName = opnDlg.FileName;
                //使用Image.FromFile创建图像对象
                try
                {
                    curBitmap = (Bitmap)Image.FromFile(curFileName);
                }
                catch (Exception exp)
                {
                    //抛出异常
                    MessageBox.Show(exp.Message);
                }
            }
            //对窗体进行重新绘制,这将强制执行paint事件处理程序
            Invalidate();
        }

        private void close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void close_Paint(object sender, PaintEventArgs e)
        {

        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (curBitmap != null)
            {
                //使用DrawImage方法绘制图像
                //160,20显示在主窗体内,图像左上角的坐标
                g.DrawImage(curBitmap, 160, 20, curBitmap.Width, curBitmap.Height);
            }
        }

        private void translation_Click(object sender, EventArgs e)
        {
            if(curBitmap!= null)
            {
                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;
                    //24为bmp位图字节数
                    int bytes = curBitmap.Width * curBitmap.Height * 3;
                    //定义位图数组
                    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];
                    //临时数组初始化为白色255像素
                    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<(curBitmap.Width*3);j++)
                            {
                                //保证横向平移不出界
                                if((j+x)< (curBitmap.Width*3)&& (j+x)>0)
                                {
                                    tempArray[(j + x) + (i + y) * curBitmap.Width*3] = grayValues[j + i * curBitmap.Width*3];
                                }
                            }
                        }
                    }
                    grayValues = (byte[])tempArray.Clone();
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }
                Invalidate();
            }
        }

        private void mirror_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;
                    //24为bmp位图字节数
                    int bytes = curBitmap.Width * curBitmap.Height * 3;
                    //定义位图数组
                    byte[] grayValues = new byte[bytes];
                    //复制被锁定的位图像素值到该数组内
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                    //水平中轴
                    int halfWidth = (curBitmap.Width*3) / 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 * curBitmap.Width*3 + j];
                                grayValues[i * curBitmap.Width*3 + j] = grayValues[(i + 1) * curBitmap.Width*3 - 1 - j];
                                grayValues[(i + 1)*curBitmap.Width*3 - 1 - j] = temp;

                            }
                        }
                    }
                    else
                    {
                        //垂直镜像处理
                        for(int i=0;i<curBitmap.Width*3;i++)
                        {
                            for(int j=0;j<halfHeight;j++)
                            {
                                //以垂直中轴线为对称轴。两边像素值互换
                                temp = grayValues[j * curBitmap.Width*3 + i];
                                grayValues[j * curBitmap.Width*3 + i] = grayValues[(curBitmap.Height - j - 1) * curBitmap.Width*3 + i];
                                grayValues[(curBitmap.Height - j - 1) * curBitmap.Width*3 + i] = temp;
                            }
                        }
                    }
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }
                Invalidate();
            }
        }
    }
}
//要注意24位灰度图像是1440万色,但是我们书上给的算法是对8为进行处理,但是我们可以采用分割的思想将24位拆开成
//3个8位,由这三个8为所保存的数据组合为24位,在处理的时候就将他们分开处理但是要整体观看
//其中的 curBit.Height*3这个处理是关键 

//以上只是主窗体里面的代码和自己的思考,方便以后复习,写的不是很好
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值