三、 实际开发中的图像操作
下面,我们来讨论实际中的使用情况。我将在本文示例应用程序中添加下列功能:
1. 以用户指定的格式保存图像。
2. 根据从菜单下选择的百分比放大图像。
3. 创建一个加载图像的略缩图。
相应的菜单操作如下所示:
mnuSave—文件菜单下保存图像的子菜单。
mnu200Zoom—放大图像200%。
mnuThumbNail—创建图像的一个略缩图。
下面是处理菜单项mnuSave的Click事件相应的方法:
private void mnuSave_Click(object sender,System.EventArgs e) ...{ //如果图像已经创建 if(curImage == null) return; //调用SaveFileDialog对话框 SaveFileDialog saveDlg = new SaveFileDialog(); saveDlg.Title = "Save Image As"; saveDlg.OverwritePrompt = true; saveDlg.CheckPathExists = true; saveDlg.Filter = "Bitmap File(*.bmp)|*.bmp|" + "Gif File(*.gif)|*.gif|" + "JPEG File(*.jpg)|*.jpg|" + "PNG File(*.png)|*.png" ; saveDlg.ShowHelp = true; //如果选择,则进行保存 if(saveDlg.ShowDialog() == DialogResult.OK) ...{ //得到用户选择的文件名 string fileName = saveDlg.FileName; //得到文件扩展名 string strFilExtn =fileName.Remove(0,fileName.Length - 3); //保存文件 switch(strFilExtn) ...{ case "bmp": curImage.Save(fileName, ImageFormat.Bmp); break; case "jpg": curImage.Save(fileName, ImageFormat.Jpeg); break; case "gif": curImage.Save(fileName, ImageFormat.Gif); break; case "tif": curImage.Save(fileName, ImageFormat.Tiff); break; case "png": curImage.Save(fileName, ImageFormat.Png); break; default: break; } } }
首先,以可接收的扩展名显示这个保存对话框。然后,由从该对话框返回的文件名检索相应的扩展名。最后,根据该扩展名,使用相应的图像格式参数调用Save()方法。
接下来,我们分析菜单项mnu200Zoom相应的处理器。首先,让我们在应用程序级添加下列以粗体显示的一行:
private double curZoom=1.0; private Image curImage=null;//用于存储当前图像 private int i = 0;//用于把屏幕重画操作与缩略图绘制部分区别开来 然后,必须对mnuLoad处理代码作少许调整,如下所示: private void mnuLoad_Click(object sender,System.EventArgs e) ...{ //创建OpenFileDialog OpenFileDialog opnDlg = new OpenFileDialog(); //设置一个图像类型过滤器 opnDlg.Filter = "All Image files|*.bmp;*.gif;*.jpg;*.ico;"+ "*.emf;,*.wmf|Bitmap Files(*.bmp;*.gif;*.jpg;"+ "*.ico)|*.bmp;*.gif;*.jpg;*.ico|"+ "Meta Files(*.emf;*.wmf;*.png)|*.emf;*.wmf;*.png"; opnDlg.Title = "打开图像文件"; opnDlg.ShowHelp = true; //如果OK,选择它 if(opnDlg.ShowDialog() == DialogResult.OK) ...{ //读取当前选择的文件名 curFileName = opnDlg.FileName; //使用Image.FromFile创建图像对象 try ...{ curImage = Image.FromFile(curFileName); } catch(Exception exp) ...{ MessageBox.Show(exp.Message); } } //改变AutoScrollMinSize属性 this.AutoScrollMinSize = new Size ((int)(curImage.Width * curZoom), (int)(curImage.Height * curZoom)); i++; //重新绘制表单 Invalidate(); }
注意,在此新添加的代码分别在原来的图像宽度和高度上乘以放大因子以生成一个放大的图像。然后,必须相应地修改paint事件的处理器。如下所示:
该图像应该有根据放大因子的相应的高度和宽度。下面,我们来看一下mnu200Zoom菜单项相应的事件处理器:private void Form1_Paint(object sender, PaintEventArgs e) ...{ if (curImage != null && i==0) ...{ Graphics g = this.CreateGraphics(); g.DrawImage(curImage, new Rectangle (AutoScrollPosition.X, AutoScrollPosition.Y , (int)(this.ClientRectangle.Width * curZoom), (int)(ClientRectangle.Height * curZoom))); } }
最后,我们来看一下mnuThumbNail菜单项相应的事件处理器:private void mnu200_Click(object sender,System.EventArgs e) ...{ if(curImage != null) ...{ curZoom = (double)200/100; i++; Invalidate(); } }
1private void mnuThumbnail_Click(object sender, EventArgs e) 2...{ 3if(curImage != null) 4...{ 5i++; 6//回调 7Image.GetThumbnailImageAbort tnCallBack = 8new Image.GetThumbnailImageAbort(tnCallbackMethod); 9//得到缩略图图像 10Image thumbNailImage = curImage.GetThumbnailImage 11(100, 100, tnCallBack, IntPtr.Zero); 12//创建一个Graphics对象 13Graphics tmpg = this.CreateGraphics(); 14tmpg.Clear(this.BackColor); 15//画缩略图图像 16tmpg.DrawImage(thumbNailImage, 10, 10, thumbNailImage.Width, thumbNailImage.Height); 17//释放掉Graphics对象 18tmpg.Dispose(); 19} 20 21} 22
在此,我们首先创建一个GetThumbnailImageAbort类型的变量并且赋给它值tnCallbackMethod()—这是通过传递给该方法GetThumbnailImageAbort实现的。然后,它创建一个新的Image类的实例以存储GetThumbnailImage方法返回的图像—此后,这个方法将用于把缩略图绘制到屏幕上。