{A}
{S0}目录
简介
前段时间,我是一个发展中的一个数字档案系统,为政府土地管理办公室的团队的一部分。基本上,系统将尝试做的是整理和数字化的管理提供了数字归档副本存档的物理文件。该系统有针对性地解决许多与文件流转速度,并发访问,和许多挂钩的问题。
发现这个系统的好处之一是进行全面细致的的访问该文件,系统的用户能够更好地查看文档比实际观看,而通过了一堆文件。由于这些文件的年龄到几十年,其中大部分是手写的,此功能是该系统的吸引力设施之一。 PictureBox控件。NET包中包含一个简单的形式显示在一个单一的形象完美,但我们需要一个更好的预览所显示的图像的实现还需要一个控制,可以处理多个图像增强的一个。
我经历了我的个人项目,并发现,我对我自己的开始,这个解决方案可能是一个起点。数字档案系统最后实施的版本功能更强大,复杂的,但依靠我转发的设计。
非常基本的需求时,观看一组图像进行彻底的访问,在小学原油条款,如下:泛变焦图像之间的导航旋转
我决定设计一个更精细的细节,可以执行这些任务很容易控制。这种控制的实施涉及未成年人基本上都是有限的坐标平移和缩放的计算。让我澄清的翻译和涉及的坐标系统。
坐标转换或到另一个。
{S2}
ImageViewer的组成部分,是大会的主要组成部分,因为这是所有的计算和命令实施。几乎每一个旋转,所有这些,我已减少到翻译中心的变焦值的显示和缩放功能,除了观看一个单独的图像时所需的命令。喜欢例如,抢夺和平移图像时,我们描述的中心和缩放功能的操作。
泛:缩放保持相同展示中心翻译在x坐标变化和y坐标的变化
下面是它是如何为所有的操作描述:private void pic_MouseMove(object sender, MouseEventArgs e)
{
//when a mouse is down and moving
//panning and region selection are posibilities
switch (previewMode)
{
case PreviewMode.REGIONSELECTION:
if (e.Button==MouseButtons.Left)
{
//display a rectangular region to the selected region
//to notify the user what he is selecting
int w = Math.Abs(tempCenter.X - e.X), h = Math.Abs(tempCenter.Y - e.Y);
if (w > 1 || h > 1)
{
this.Refresh();
Graphics gr = pic.CreateGraphics();
gr.DrawString("(" + (tempCenter.X + e.X) / 2 + "," +
(tempCenter.Y + e.Y) / 2 + ")", this.Font,
Brushes.Khaki, new PointF((tempCenter.X + e.X) / 2,
(tempCenter.Y + e.Y) / 2));
gr.DrawRectangle(Pens.Red, new Rectangle((tempCenter.X + e.X - w) / 2,
(tempCenter.Y + e.Y - h) / 2, w, h));
gr.Dispose();
}
}
break;
case PreviewMode.PAN:
if (e.Button==MouseButtons.Left&&(tempCenter.X != e.X ||
tempCenter.Y != e.Y))
{
displayCenter = new Point(displayCenter.X +
(int)((tempCenter.X- e.X ) / mZoom),
displayCenter.Y + (int)((tempCenter.Y-e.Y) / mZoom));
ZoomImage();
tempCenter = e.Location;
}
break;
default:
break;
}
}
private void pic_MouseUp(object sender, MouseEventArgs e)
{
//when the mouse is up its when most of the previews are commited
switch (previewMode)
{
case PreviewMode.REGIONSELECTION:
displayCenter = new Point(displayCenter.X +
(int)(((double)(tempCenter.X + e.X - this.Width) / 2) / mZoom),
displayCenter.Y + (int)(((double)(tempCenter.Y +
e.Y - this.Height) / 2) / mZoom));
double z = mZoom * pic.Width / Math.Abs(tempCenter.X - e.X);
if (mZoom * pic.Height / Math.Abs(tempCenter.Y - e.Y) < z)
z = mZoom * pic.Height / Math.Abs(tempCenter.Y - e.Y);
mZoom = z;
ZoomImage();
break;
case PreviewMode.ZOOMIN:
//when zoom in the zoom value is simply multiplied by two
displayCenter=new Point(displayCenter.X+(int)((e.X-this.Width/2)/mZoom),
displayCenter.Y+(int)((e.Y-this.Height/2)/mZoom));
mZoom *= 2;
//redraw the image with the new zoom value
ZoomImage();
break;
case PreviewMode.ZOOMOUT:
//when zoom out the zoom value is simply divided by two
displayCenter = new Point(displayCenter.X +
(int)((e.X - this.Width / 2) / mZoom),
displayCenter.Y + (int)((e.Y - this.Height / 2) / mZoom));
mZoom /= 2;
//redraw the image with the new zoom value
ZoomImage();
break;
default:
break;
}
}
所示的代码,每个case语句的专用计算最重要的两个产生的图像,以显示所需的变量。一旦这些值计算,如果你调用的方法ZoomImage(),它有效地用新值重绘图像。类图部分看起来像:
{S3}实施托管图像查看器组件
此组件拥有所有所需的命令,并准备为消费者代码,但果汁,并提供一个非常有用的和有效的浏览器控制,您需要到主机这就像在一个用户控件,并提供事件来触发这些命令。随着这篇文章中,我已经包括一个灵活的主机控制,易于使用,如图片所示:
{S4}的
这种控制工具框如下图实施的所有基本工具。每个可用命令的按钮和下拉式清单中暴露。例如,组件的变焦能力是暴露的下拉列表中的事件处理程序的下降,在下面的代码示例:{C}
为了减少代码我应该写来提取的变焦模式枚举量,我使出解析字符串的枚举值,否则,它的一个简单的方法揭露的的图像查看器组件放大图像的方法。同样的故事与工具条按钮除,我已经使用每个按钮来存储各自的枚举值的标签,让我不会有切换??情况下,或者如果??其他所有案件和唐"没有处理所有按钮的Click事件。正如在下面的代码示例描述:
{A11}图片来源private void btn_Click(object sender, EventArgs e)
{
img.ImagePreviewMode = (PreviewMode)Enum.Parse(typeof(PreviewMode),
((ToolStripButton)sender).Tag.ToString());
btnPan.Checked = img.ImagePreviewMode == PreviewMode.PAN;
btnRegionZoom.Checked = img.ImagePreviewMode == PreviewMode.REGIONSELECTION;
btnZoomIn.Checked = img.ImagePreviewMode == PreviewMode.ZOOMIN;
btnZoomOut.Checked = img.ImagePreviewMode == PreviewMode.ZOOMOUT;
switch (img.ImagePreviewMode)
{
case PreviewMode.PAN:
this.Cursor = Cursors.Hand;
break;
case PreviewMode.REGIONSELECTION:
this.Cursor = Cursors.Cross;
break;
default:
this.Cursor = Cursors.Default;
break;
}
}
,并非所有的是,在大多数情况下,图像源是一个系统试图显示一个图像文件的文件系统。但在任何情况下,图像查看器组件接受任何形象只要源作为对象实现IZImage的接口,其定义是在下面的代码所示:/// <summary>
/// a signiture interface that when implemented by any object
/// enables it to utilize the image viewer component
/// </summary>
public interface IZImage
{
//gets the number of images that are available for display
int ImageCount{ get;}
//gets the current index of the image that is being displayed
int CurrentIndex { get;}
//retreives the next available image
Image GetNextImage();
//retrieves the previously displayed image
Image GetPreviousImage();
}
在本文附带的示例代码中,有两个样本中实现sample.cs和PictureBoxEx.cs文件的IZImage接口。在样品的实施,我写了一个简单的代码,显示目录中的图像。我创建了一个类调用的代码> DirectoryImages,其定义如下所示???public class DirectoryImages:IZImage
{
//path of the directory
string m_DirectoryName;
//number of the image files that are found
int m_ImageFilesCount;
int m_CurrentIndex=-1;
string[] ImageFiles;
public DirectoryImages(string str)
{
m_DirectoryName = str;
ImageFiles = Directory.GetFiles(str, "*.jpg");
m_ImageFilesCount = ImageFiles.Length;
}
#region IZImage Members
public int ImageCount
{
get { return m_ImageFilesCount; }
}
public int CurrentIndex
{
get { return m_CurrentIndex; }
}
public System.Drawing.Image GetNextImage()
{
m_CurrentIndex++;
if (m_CurrentIndex >= m_ImageFilesCount)
throw new Exception("No More Images");
return System.Drawing.Image.FromFile(ImageFiles[m_CurrentIndex]);
}
public System.Drawing.Image GetPreviousImage()
{
m_CurrentIndex--;
if (m_CurrentIndex <= 0)
throw new Exception("No More Images");
return System.Drawing.Image.FromFile(ImageFiles[m_CurrentIndex]);
}
#endregion
}
代码所示,该对象需要的目录路径,并显示该目录中的"JPG图像?延伸,一个接一个。要显示任何图像从任何来源获取一个对象,实施??代码> IZImage??接口,传递对象的存取控制。为了快速使用此图像浏览器,通读下一节。{A12}快速实施
计算机OOP的最伟大的成就之一是抽象的细节和事实,以使用一个类,你不需要知道它是如何做。因此,我提供了一个的存取控制,以便为它表现为一个图片框的默认实现;?这个定义可以发现在EM> PictureBoxEx.cs文件??
当你去通过的代码,你会发现,基本上有两种实现方式:存取控制(PictureBoxEx)和图像源类(ImageFile)。
示例应用程序
示例应用程序,我希望最好的编译说明使用这个增强的图像浏览器的电源。您可以使用"文件"菜单中打开一个单独的图像文件或浏览通过指定的文件夹在一个文件夹中的图像。
{五}{A13}结论
在我的结论,你可以建立复杂的主机控制此组件,甚至不担心组件中所涉及的计算,例如,采用鼠标中放大和缩小。我希望这个组件将有很大的帮助,给任何人,希望利用它。| samqty"