-- 作者:卷积内核
-- 发布时间:7/11/2014 9:25:00 AM
-- C# 图片截取
代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Windows.Forms; using System.Reflection; /* * 实现图片剪切 * */ namespace CutImage { public partial class frmMain : Form { public frmMain() { InitializeComponent(); } /// <summary> /// 打开图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnOpen_Click(object sender, EventArgs e) { string strFilename = ""; OpenFileDialog dlgOpen = null; try { dlgOpen = new OpenFileDialog(); dlgOpen.Filter = "All Image Files(*.*)|*.*"; if (dlgOpen.ShowDialog() == DialogResult.OK) { if (dlgOpen.FileName == "") return; strFilename = dlgOpen.FileName; pbxOriImage.Image = Image.FromFile(strFilename); this.SetImageSizeMode(pbxOriImage); } } catch (Exception ex) { MessageBox.Show("无法识别的图片格式(" + strFilename + ")\r\n" + ex.Message , "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { if (dlgOpen != null) dlgOpen.Dispose(); dlgOpen = null; } } /// <summary> /// 设置图片显示模式 /// </summary> /// <param name="pImage"></param> private void SetImageSizeMode(PictureBox pImage) { if (pImage == null) return; Image imgResult = pImage.Image; if (imgResult != null) { //控制图片显示方式 if (imgResult.Width > pImage.Width || imgResult.Height > pImage.Height) { pImage.SizeMode = PictureBoxSizeMode.Zoom; } else { pImage.SizeMode = PictureBoxSizeMode.CenterImage; } } } #region 绘制及剪切 Point fPtStart; //开始位置矩形的位置 bool fHaveImage = false; //是否有图片 Point fPtFirst; //鼠标按下去的位置 Point fPtSecond; //鼠标当前位置 /// <summary> /// 记录鼠标按下去的位置 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pbxOriImage_MouseDown(object sender, MouseEventArgs e) { this.Cursor = Cursors.Cross; fPtFirst = new Point(e.X, e.Y); fPtStart = new Point(e.X, e.Y); if ((sender as PictureBox).Image != null) { this.fHaveImage = true; } else { this.fHaveImage = false; } } private void pbxOriImage_MouseMove(object sender, MouseEventArgs e) { if (this.Cursor == Cursors.Cross) { fPtSecond = new Point(e.X, e.Y); if ((fPtSecond.X - fPtFirst.X) > 0 && (fPtSecond.Y - fPtFirst.Y) > 0) { //鼠标当前位置在,按下去位置的右下角 fPtStart = new Point(fPtFirst.X, fPtFirst.Y); } else if ((fPtSecond.X - fPtFirst.X) > 0 && (fPtSecond.Y - fPtFirst.Y) < 0) { //鼠标当前位置在,按下去位置的右上角 fPtStart = new Point(fPtFirst.X, fPtSecond.Y); } else if ((fPtSecond.X - fPtFirst.X) < 0 && (fPtSecond.Y - fPtFirst.Y) > 0) { //鼠标当前位置在,按下去位置的左下角 fPtStart = new Point(fPtSecond.X, fPtFirst.Y); } else { //鼠标当前位置在,按下去位置的左上角 fPtStart = new Point(fPtSecond.X, fPtSecond.Y); } pbxOriImage.Invalidate(); //移动时绘制矩形选择框 } } /// <summary> /// 剪切图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pbxOriImage_MouseUp(object sender, MouseEventArgs e) { if (this.fHaveImage == false) return; try { fPtSecond = new Point(e.X, e.Y); if ((fPtSecond.X - fPtFirst.X) > 0 && (fPtSecond.Y - fPtFirst.Y) > 0) { //鼠标当前位置在,按下去位置的右下角 fPtStart = new Point(fPtFirst.X, fPtFirst.Y); } else if ((fPtSecond.X - fPtFirst.X) > 0 && (fPtSecond.Y - fPtFirst.Y) < 0) { //鼠标当前位置在,按下去位置的右上角 fPtStart = new Point(fPtFirst.X, fPtSecond.Y); } else if ((fPtSecond.X - fPtFirst.X) < 0 && (fPtSecond.Y - fPtFirst.Y) > 0) { //鼠标当前位置在,按下去位置的左下角 fPtStart = new Point(fPtSecond.X, fPtFirst.Y); } else { //鼠标当前位置在,按下去位置的左上角 fPtStart = new Point(fPtSecond.X, fPtSecond.Y); } Rectangle rectDisplay = this.GetPictureDisplaySize(pbxOriImage); //图片实际显示的大小 int Width = Math.Abs((fPtSecond.X - fPtFirst.X)); int Height = Math.Abs((fPtSecond.Y - fPtFirst.Y)); double dWRate = pbxOriImage.Image.Width / (double)rectDisplay.Width; //缩放比例:宽 double dHRate = pbxOriImage.Image.Height / (double)rectDisplay.Height; //缩放比例:高 int intRealWidth = (int)(dWRate * Width); //实际需要截取的图片宽度 int intRealHeight = (int)(dHRate * Height); //实际需要截取的图片高度 int intRealX = (int)((fPtStart.X - rectDisplay.X) * dWRate); //实际的X坐标 int intRealY = (int)((fPtStart.Y - rectDisplay.Y) * dHRate); //实际的Y坐标 Bitmap bmpDest = new Bitmap(intRealWidth, intRealHeight, PixelFormat.Format32bppRgb); //目标图片大小 Graphics g = Graphics.FromImage(bmpDest); //创建GDI Rectangle rectDest = new Rectangle(0, 0, intRealWidth, intRealHeight); Rectangle rectSource = new Rectangle(intRealX,intRealY, intRealWidth, intRealHeight); g.DrawImage(pbxOriImage.Image, rectDest, rectSource, GraphicsUnit.Pixel); //绘图 pbxCutImage.Image = (Image)bmpDest; g.Dispose(); SetImageSizeMode(pbxCutImage); } catch (Exception ex) { MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { this.Cursor = Cursors.Default; } } /// <summary> /// 获取图片实际显示的大小 /// </summary> /// <param name="pbxImage"></param> /// <returns></returns> public Rectangle GetPictureDisplaySize(PictureBox pbxImage) { if (pbxImage != null) { PropertyInfo ppiImageRect = pbxImage.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic); return (Rectangle)ppiImageRect.GetValue(pbxImage, null); } return new Rectangle(0, 0, 1, 1); } /// <summary> /// 绘制矩形选择框 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pbxOriImage_Paint(object sender, PaintEventArgs e) { int intWidth = 0; int intHeight = 0; if (this.fHaveImage == true) { Pen p = new Pen(Color.Black, 1); p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; intWidth = Math.Abs(fPtFirst.X - fPtSecond.X); intHeight = Math.Abs(fPtFirst.Y - fPtSecond.Y); Rectangle rectDraw = new Rectangle(fPtStart, new Size(intWidth, intHeight)); e.Graphics.DrawRectangle(p, rectDraw); } } #endregion /// <summary> /// 保存剪切后的图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSave_Click(object sender, EventArgs e) { SaveFileDialog dlgSave = new SaveFileDialog(); if (dlgSave.ShowDialog() == DialogResult.OK) { pbxCutImage.Image.Save(dlgSave.FileName); } } } }
|