C# 实现QQ式截图功能
这个功能一共有两部分组成,第一部分是窗体代码,另外的一部分是一个辅助方法。直接贴出代码,以供大家参考:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Drawing.Drawing2D; 10 using System.Drawing.Imaging; 11 using ImageClassLib; 12 namespace ImageShear 13 { 14 public partial class Demo: Form 15 { 16 public Demo() 17 { 18 InitializeComponent(); 19 } 20 #region 点击打开图像 21 public string strHeadImagePath; //打开图片的路径 22 Bitmap Bi; //定义位图对像 23 private void button1_Click(object sender, EventArgs e) 24 { 25 openFileDialog1.Filter = "*.gif|*.jpg|*.JPEG|*.JPEG|*.bmp|*.bmp"; //设置读取图片类型 26 if (openFileDialog1.ShowDialog() == DialogResult.OK) 27 { 28 try 29 { 30 strHeadImagePath = openFileDialog1.FileName; 31 //this.Show(strHeadImagePath); 32 Bi = new Bitmap(strHeadImagePath); //使用打开的图片路径创建位图对像 33 ImageCut1 IC = new ImageCut1(40, 112, this.pictureBox1.Width, this.pictureBox1.Height); //实例化ImageCut类,四个参数据分别表示为:x、y、width、heigth,(40、112)表示pictureBox1的Lcation的坐标,(120、144)表示pictureBox1控件的宽度和高度 34 this.pictureBox1.Image = IC.KiCut1((Bitmap)(this.GetSelectImage(this.pictureBox1.Width, this.pictureBox1.Height))); //(120、144)表示pictureBox1控件的宽度和高度 35 //this.pictureBox1.Image = (this.GetSelectImage(120, 144)); 36 } 37 catch (Exception ex) 38 { 39 MessageBox.Show("格式不对"); 40 ex.ToString(); 41 } 42 } 43 } 44 #endregion 45 #region 定义显示图像方法,即将打开的图像在pictureBox1控件显示 46 public void Show(string strHeadImagePath) 47 { 48 this.pictureBox1.Load(@strHeadImagePath); // 49 } 50 #endregion 51 #region 获取图像 52 /// <summary> 53 /// 获取指定宽度和高度的图像即使图片和pictureBox1控件一样宽和高,返回值为图片Image 54 /// </summary> 55 /// <param name="Width表示宽"></param> 56 /// <param name="Height表示高"></param> 57 /// <returns></returns> 58 public Image GetSelectImage(int Width, int Height) 59 { 60 //Image initImage = this.pictureBox1.Image; 61 Image initImage = Bi; 62 //原图宽高均小于模版,不作处理,直接保存 63 if (initImage.Width <= Width && initImage.Height <= Height) 64 { 65 //initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg); 66 return initImage; 67 } 68 else 69 { 70 //原始图片的宽、高 71 int initWidth = initImage.Width; 72 int initHeight = initImage.Height; 73 74 //非正方型先裁剪为正方型 75 if (initWidth != initHeight) 76 { 77 //截图对象 78 System.Drawing.Image pickedImage = null; 79 System.Drawing.Graphics pickedG = null; 80 81 //宽大于高的横图 82 if (initWidth > initHeight) 83 { 84 //对象实例化 85 pickedImage = new System.Drawing.Bitmap(initHeight, initHeight); 86 pickedG = System.Drawing.Graphics.FromImage(pickedImage); 87 //设置质量 88 pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 89 pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 90 //定位 91 Rectangle fromR = new Rectangle((initWidth - initHeight) / 2, 0, initHeight, initHeight); 92 Rectangle toR = new Rectangle(0, 0, initHeight, initHeight); 93 //画图 94 pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel); 95 //重置宽 96 initWidth = initHeight; 97 } 98 //高大于宽的竖图 99 else 100 { 101 //对象实例化 102 pickedImage = new System.Drawing.Bitmap(initWidth, initWidth); 103 pickedG = System.Drawing.Graphics.FromImage(pickedImage); 104 //设置质量 105 pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 106 pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 107 //定位 108 Rectangle fromR = new Rectangle(0, (initHeight - initWidth) / 2, initWidth, initWidth); 109 Rectangle toR = new Rectangle(0, 0, initWidth, initWidth); 110 //画图 111 pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel); 112 //重置高 113 initHeight = initWidth; 114 } 115 116 initImage = (System.Drawing.Image)pickedImage.Clone(); 117 // //释放截图资源 118 pickedG.Dispose(); 119 pickedImage.Dispose(); 120 } 121 122 return initImage; 123 } 124 } 125 #endregion 126 #region 点击button2按钮事件 127 private void button2_Click(object sender, EventArgs e) 128 { 129 this.label1.Text = "裁剪后的图片宽度:"+this.pictureBox2.Width.ToString(); 130 this.label2.Text = "裁剪后的图片高度:"+this.pictureBox2.Height.ToString(); 131 } 132 #endregion 133 #region 缩放、裁剪图像用到的变量 134 /// <summary> 135 /// 136 /// </summary> 137 int x1; //鼠标按下时横坐标 138 int y1; //鼠标按下时纵坐标 139 int width; //所打开的图像的宽 140 int heigth; //所打开的图像的高 141 bool HeadImageBool = false; // 此布尔变量用来判断pictureBox1控件是否有图片 142 #endregion 143 #region 画矩形使用到的变量 144 Point p1; //定义鼠标按下时的坐标点 145 Point p2; //定义移动鼠标时的坐标点 146 Point p3; //定义松开鼠标时的坐标点 147 #endregion 148 #region 鼠标按下时发生的事件 149 private void pictureBox1_MouseDown(object sender, MouseEventArgs e) 150 { 151 this.Cursor = Cursors.Cross; 152 this.p1 = new Point(e.X, e.Y); 153 x1 = e.X; 154 y1 = e.Y; 155 if (this.pictureBox1.Image != null) 156 { 157 HeadImageBool = true; 158 } 159 else 160 { 161 HeadImageBool = false; 162 } 163 } 164 #endregion 165 #region 移动鼠标发生的事件 166 private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 167 { 168 if (this.Cursor == Cursors.Cross) 169 { 170 this.p2 = new Point(e.X, e.Y); 171 if ((p2.X - p1.X) > 0 && (p2.Y - p1.Y) > 0) //当鼠标从左上角向开始移动时P3坐标 172 { 173 this.p3 = new Point(p1.X, p1.Y); 174 } 175 if ((p2.X - p1.X) < 0 && (p2.Y - p1.Y) > 0) //当鼠标从右上角向左下方向开始移动时P3坐标 176 { 177 this.p3 = new Point(p2.X, p1.Y); 178 } 179 if ((p2.X - p1.X) > 0 && (p2.Y - p1.Y) < 0) //当鼠标从左下角向上开始移动时P3坐标 180 { 181 this.p3 = new Point(p1.X, p2.Y); 182 } 183 if ((p2.X - p1.X) < 0 && (p2.Y - p1.Y) < 0) //当鼠标从右下角向左方向上开始移动时P3坐标 184 { 185 this.p3 = new Point(p2.X, p2.Y); 186 } 187 this.pictureBox1.Invalidate(); //使控件的整个图面无效,并导致重绘控件 188 } 189 } 190 #endregion 191 #region 松开鼠标发生的事件,实例化ImageCut1类对像 192 ImageCut1 IC1; //定义所画矩形的图像对像 193 private void pictureBox1_MouseUp(object sender, MouseEventArgs e) 194 { 195 if (HeadImageBool) 196 { 197 width = this.pictureBox1.Image.Width; 198 heigth = this.pictureBox1.Image.Height; 199 if ((e.X - x1) > 0 && (e.Y - y1) > 0) //当鼠标从左上角向右下方向开始移动时发生 200 { 201 IC1 = new ImageCut1(x1, y1, Math.Abs(e.X - x1), Math.Abs(e.Y - y1)); //实例化ImageCut1类 202 } 203 if ((e.X - x1) < 0 && (e.Y - y1) > 0) //当鼠标从右上角向左下方向开始移动时发生 204 { 205 IC1 = new ImageCut1(e.X, y1, Math.Abs(e.X - x1), Math.Abs(e.Y - y1)); //实例化ImageCut1类 206 } 207 if ((e.X - x1) > 0 && (e.Y - y1) < 0) //当鼠标从左下角向右上方向开始移动时发生 208 { 209 IC1 = new ImageCut1(x1, e.Y, Math.Abs(e.X - x1), Math.Abs(e.Y - y1)); //实例化ImageCut1类 210 } 211 if ((e.X - x1) < 0 && (e.Y - y1) < 0) //当鼠标从右下角向左上方向开始移动时发生 212 { 213 IC1 = new ImageCut1(e.X, e.Y, Math.Abs(e.X - x1), Math.Abs(e.Y - y1)); //实例化ImageCut1类 214 } 215 this.pictureBox2.Width = (IC1.KiCut1((Bitmap)(this.pictureBox1.Image))).Width; 216 this.pictureBox2.Height = (IC1.KiCut1((Bitmap)(this.pictureBox1.Image))).Height; 217 this.pictureBox2.Image = IC1.KiCut1((Bitmap)(this.pictureBox1.Image)); 218 this.Cursor = Cursors.Default; 219 } 220 else 221 { 222 this.Cursor = Cursors.Default; 223 } 224 } 225 #endregion 226 #region 获取所选矩形图像 227 /// <summary> 228 /// 229 /// </summary> 230 /// <param name="Width"></param> 231 /// <param name="Height"></param> 232 /// <returns></returns> 233 public Image GetSelectImage1(int Width, int Height) 234 { 235 Image initImage = this.pictureBox1.Image; 236 //Image initImage = Bi; 237 //原图宽高均小于模版,不作处理,直接保存 238 if (initImage.Width <= Width && initImage.Height <= Height) 239 { 240 //initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg); 241 return initImage; 242 } 243 else 244 { 245 //原始图片的宽、高 246 int initWidth = initImage.Width; 247 int initHeight = initImage.Height; 248 249 //非正方型先裁剪为正方型 250 if (initWidth != initHeight) 251 { 252 //截图对象 253 System.Drawing.Image pickedImage = null; 254 System.Drawing.Graphics pickedG = null; 255 256 //宽大于高的横图 257 if (initWidth > initHeight) 258 { 259 //对象实例化 260 pickedImage = new System.Drawing.Bitmap(initHeight, initHeight); 261 pickedG = System.Drawing.Graphics.FromImage(pickedImage); 262 //设置质量 263 pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 264 pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 265 //定位 266 Rectangle fromR = new Rectangle((initWidth - initHeight) / 2, 0, initHeight, initHeight); 267 Rectangle toR = new Rectangle(0, 0, initHeight, initHeight); 268 //画图 269 pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel); 270 //重置宽 271 initWidth = initHeight; 272 } 273 //高大于宽的竖图 274 else 275 { 276 //对象实例化 277 pickedImage = new System.Drawing.Bitmap(initWidth, initWidth); 278 pickedG = System.Drawing.Graphics.FromImage(pickedImage); 279 //设置质量 280 pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 281 pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 282 //定位 283 Rectangle fromR = new Rectangle(0, (initHeight - initWidth) / 2, initWidth, initWidth); 284 Rectangle toR = new Rectangle(0, 0, initWidth, initWidth); 285 //画图 286 pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel); 287 //重置高 288 initHeight = initWidth; 289 } 290 291 initImage = (System.Drawing.Image)pickedImage.Clone(); 292 // //释放截图资源 293 pickedG.Dispose(); 294 pickedImage.Dispose(); 295 } 296 297 return initImage; 298 } 299 } 300 #endregion 301 #region 重新绘制pictureBox1控件,即移动鼠标画矩形 302 private void pictureBox1_Paint(object sender, PaintEventArgs e) 303 { 304 if (HeadImageBool) 305 { 306 Pen p = new Pen(Color.Black, 1);//画笔 307 p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; 308 //Bitmap bitmap = new Bitmap(strHeadImagePath); 309 Bitmap bitmap = Bi; 310 Rectangle rect = new Rectangle(p3, new Size(System.Math.Abs(p2.X - p1.X), System.Math.Abs(p2.Y - p1.Y))); 311 e.Graphics.DrawRectangle(p, rect); 312 } 313 else 314 { 315 316 } 317 } 318 #endregion 319 } 320 }
第二部分是辅助方法类
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Drawing; 6 using System.Drawing.Drawing2D; 7 using System.Drawing.Imaging; 8 namespace ImageClassLib 9 { 10 public class ImageCut1 11 { 12 #region 剪裁图片方法 13 /// <summary> 14 /// 剪裁 -- 用GDI+ 15 /// </summary> 16 /// <param name="b">原始Bitmap,即需要裁剪的图片</param> 17 /// <param name="StartX">开始坐标X</param> 18 /// <param name="StartY">开始坐标Y</param> 19 /// <param name="iWidth">宽度</param> 20 /// <param name="iHeight">高度</param> 21 /// <returns>剪裁后的Bitmap</returns> 22 public Bitmap KiCut1(Bitmap b) 23 { 24 if (b == null) 25 { 26 return null; 27 } 28 29 int w = b.Width; 30 int h = b.Height; 31 32 if (X >= w || Y >= h) 33 { 34 return null; 35 } 36 37 if (X + Width > w) 38 { 39 Width = w - X; 40 } 41 42 if (Y + Height > h) 43 { 44 Height = h - Y; 45 } 46 47 try 48 { 49 Bitmap bmpOut = new Bitmap(Width, Height, PixelFormat.Format24bppRgb); 50 51 Graphics g = Graphics.FromImage(bmpOut); 52 // Create rectangle for displaying image. 53 Rectangle destRect = new Rectangle(0, 0, Width, Height); //所画的矩形正确,它指定所绘制图像的位置和大小。 将图像进行缩放以适合该矩形。 54 55 // Create rectangle for source image. 56 Rectangle srcRect = new Rectangle(X, Y, Width, Height); //srcRect参数指定要绘制的 image 对象的矩形部分。 将此部分进行缩放以适合 destRect 参数所指定的矩形。 57 58 g.DrawImage(b, destRect, srcRect, GraphicsUnit.Pixel); 59 //resultG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, side, side), new System.Drawing.Rectangle(0, 0, initWidth, initHeight), System.Drawing.GraphicsUnit.Pixel); 60 g.Dispose(); 61 return bmpOut; 62 } 63 catch 64 { 65 return null; 66 } 67 } 68 #endregion 69 #region ImageCut1类的构造函数 70 public int X; 71 public int Y; 72 public int Width ; 73 public int Height; 74 /// <summary> 75 /// ImageCut1类的构造函数,ImageCut1类用来获取鼠标在pictureBox1控件所画矩形内的图像 76 /// </summary> 77 /// <param name="x表示鼠标在pictureBox1控件上按下时的横坐标"></param> 78 /// <param name="y表示鼠标在pictureBox1控件上按下时的纵坐标"></param> 79 /// <param name="width表示鼠标在pictureBox1控件上松开鼠标的宽度"></param> 80 /// <param name="heigth表示鼠标在pictureBox1控件上松开鼠标的高度"></param> 81 public ImageCut1(int x, int y, int width, int heigth) 82 { 83 X = x; 84 Y = y; 85 Width = width; 86 Height = heigth; 87 } 88 #endregion 89 } 90 }
实现的效果如下: