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这个处理是关键
//以上只是主窗体里面的代码和自己的思考,方便以后复习,写的不是很好