C#数字图像处理算法学习笔记(三)--图像几何变换
几何图像处理包括 图像的平移变换,镜像变换,旋转变换,伸缩变换,在这里仅以水平镜像为例,通过代码来理解其基本操作方式:
翻转前:
翻转后:
//后台代码:
public partial class Form1 : Form
{
private string _curFileName;
private Bitmap _srcBitmap;
private Bitmap _dstBitmap;
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;*.wmf;*.eps;*.emf";
opnDlg.Title = @"打开图像文件";
opnDlg.ShowHelp = true;
if (opnDlg.ShowDialog() == DialogResult.OK)
{
_curFileName = opnDlg.FileName;
try
{
_srcBitmap = (Bitmap) Image.FromFile(_curFileName);
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
}
Invalidate();
}
private void close_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
if (_srcBitmap != null)
{
g.DrawImage(_srcBitmap, 160, 20, _srcBitmap.Width, _srcBitmap.Height);
}
}
//翻转处理函数,这里是通过两幅图来进行翻转操作,也可以用一幅图直接翻转,只不过要特别注意每个像素占3个byte位,且翻转时是整个像素一起翻转
private void mirror_Click(object sender, EventArgs e)
{
if (_srcBitmap != null)
{
_dstBitmap = (Bitmap) _srcBitmap.Clone();
BitmapData bmpData = _srcBitmap.LockBits(new Rectangle(0, 0, _srcBitmap.Width, _srcBitmap.Height),
ImageLockMode.ReadWrite,
_srcBitmap.PixelFormat);
BitmapData dstData = _dstBitmap.LockBits(new Rectangle(0, 0, _dstBitmap.Width, _dstBitmap.Height),
ImageLockMode.ReadWrite, _dstBitmap.PixelFormat);
unsafe
{
byte* p = (byte*) bmpData.Scan0;
for (int y = 0; y < bmpData.Height; y++)
{
for (int x = 0; x < bmpData.Width; x++)
{
byte* dstp = (byte*) dstData.Scan0 + y*dstData.Stride + x*3;
dstp[0] = p[bmpData.Width*3 - (x + 1)*3];
dstp[1] = p[bmpData.Width*3 - (x + 1)*3 + 1];
dstp[2] = p[bmpData.Width*3 - (x + 1)*3 + 2];
}
p += bmpData.Stride; //Stride 为扫描宽度 Stride > bmpData.Width * 3 ,Width 表示每行的像素个数,每个像素占3个byte位
}
_srcBitmap.UnlockBits(bmpData);
_dstBitmap.UnlockBits(dstData);
}
_srcBitmap = (Bitmap) _dstBitmap.Clone();
Invalidate();
}
}
}
其它几何处理类似于这个操作,在通过指针直接在原数据上操作,但要特别注意指针的越界检查。