处理图像
图像裁剪:
Graphics g = e.Graphics; Bitmap bmp = new Bitmap("a.jpg"); g.FillRectangle(Brushes.White, this.ClientRectangle); Rectangle sr = new Rectangle(80, 60, 400, 400); Rectangle dr = new Rectangle(0, 0, 200, 200); g.DrawImage(bmp, dr, sr, GraphicsUnit.Pixel);
源矩形定义了修剪后要在原图像中保留的那一部分,目标矩形描述了在绘图表面中绘制结果图像的位置以及结果图像的大小。
变形、翻转和旋转图像
DrawImage方法的一个重载方法允许把一个三点数组作为一个参数传送给他,这三个点在绘制图像时执行下述函数:第一点指定原位图的左上角点的目标位置;第二点指定原位图的右上角点的目标位置;第三点指定源位图的左下角点的目标位置。
Graphics g = e.Graphics; Bitmap bmp = new Bitmap("a.jpg"); g.FillRectangle(Brushes.White, this.ClientRectangle); Point[] destinationPoints = { new Point(0, 0), new Point(100, 0), new Point(50, 100) }; g.DrawImage(bmp, destinationPoints);
复制图像
下面的代码演示了如何拷贝现有bitmap对象的一部分,创建一个新的bitmap对象:
Graphics g = e.Graphics; Bitmap bmp = new Bitmap("a.jpg"); g.FillRectangle(Brushes.White, this.ClientRectangle); Rectangle r = new Rectangle(10,10, 20, 20); Bitmap bmp2 = bmp.Clone(r, System.Drawing.Imaging.PixelFormat.DontCare); g.DrawImage(bmp, new Rectangle(0, 0, 200, 200)); g.DrawImage(bmp2, new Rectangle(210, 0, 200, 200)); bmp2.Dispose();
注意在指定源矩形时,需要确保该矩形在源图像的边界之内,如果不是这样,就会得到一个System.OutOfException异常。
创建和绘制图像
Bitmap bmp = new Bitmap(width,height)得到一个新Bitmap对象,他表示内存中一个位图,且其pixelformat是format32bppARGB
BItmap bmp = new Bitmap(width,height,pixelformat)这里pixelformat是其枚举中的一个值
Bitmap bmp = new Bitmap(width,height,g)得到一个新的bitmap对象,他表示内存中的一个位图,且其分辨率和颜色深度与指定的绘图表面相同(g是绘图表面的graphics对象)
Bitmap bmp = new Bitmap(100, 100); Graphics gImage = Graphics.FromImage(bmp); gImage.FillRectangle(Brushes.Red, 0, 0, bmp.Width, bmp.Height); gImage.DrawRectangle(Pens.Black, 10, 10, bmp.Width - 20, bmp.Height - 20);
Graphics gScreen = e.Graphics; gScreen.FillRectangle(Brushes.White, this.ClientRectangle); gScreen.DrawImage(bmp, new Rectangle(10, 10, bmp.Width, bmp.Height));
这里使用了Graphics类的两个实例,第一个gImage表示图像的绘图表面,第二个实例gScreen表示窗体的绘图表面,是图像的最终目的地。
将上述代码分开实现,实现创建和绘制位图,再把该位图绘制到窗体上,而不是直接绘制到窗体上,这样,就可以提前绘制图像,只需绘制一次图形,而不是在每次接收到paint时间是都绘制它们。
双倍缓存
双倍缓存技术允许事先准备图形,再在一次操作中把它们绘制到屏幕上。为了激活双倍缓存功能需要使用form类的setstyle方法,把下面的代码放在窗体的构造函数中,或放在窗体的load事件中,就可以激活双倍缓存功能:
SetStyle(ControlStyles.DoubleBuffer, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.UserPaint, true);
AllPaintinginWmPaint和 UserPaint设置为true时,架构不会绘制控件的任何一部分,包括控件的背景。
Graphics类的CompositingMode属性可以控制操作时混合图像还是用它的alpha信息改写图像,其中,SourceCopy表示绘图颜色和alpha改写图像上已有的位,SourceOver表示绘图操作与图像的已有像素混合起来,这种混合取决于绘图颜色的alpha成分。
Graphics gForm = e.Graphics; gForm.FillRectangle(Brushes.White, this.ClientRectangle); for (int i = 0; i <= 7; ++i) { Rectangle r = new Rectangle(i * 40 - 15, 0, 15, this.ClientRectangle.Height); gForm.FillRectangle(Brushes.Orange, r); } Bitmap bmp = new Bitmap(260, 260,System.Drawing.Imaging.PixelFormat.Format32bppArgb); Graphics gBmp = Graphics.FromImage(bmp); gBmp.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; Color red = Color.FromArgb(0x60, 0xff, 0, 0); Brush redBrush = new SolidBrush(red); gBmp.FillEllipse(redBrush, 70, 70, 160, 160); Color green = Color.FromArgb(0x40, 0, 0xff, 0); Brush greenBrush = new SolidBrush(green); gBmp.FillRectangle(greenBrush, 10, 10, 140, 140); gForm.DrawImage(bmp, 20, 20, bmp.Width, bmp.Height); bmp.Dispose(); gBmp.Dispose(); redBrush.Dispose(); greenBrush.Dispose();
这里有两个graphics对象,gform表示窗体绘图表面,gbmp表示内存中的位图,我们把位图的compositingmode属性设置为sourcecopy,这样绿色方块就会覆盖位图中的红色圆,但没有为窗体绘图表面的compositingmode属性指定为gform,因此,他使用默认值sourceover,这样在橙色条上绘制位图图像时,圆和方块就会与条纹混合在一起。
把bmp文件转换为JPEG文件,可以使用下面的代码:
Bitmap bmp = new Bitmap(“a.bmp”);
bmp.save(”a.jpg“,System.Drawing.Imaging.ImageFormat.Jpeg);