ASP.net, C# 中实现图像缩放、裁剪和平移,类似 Google 地图。






2.20/5 (4投票s)
2006年12月26日
3分钟阅读

51266

2462
一篇关于图像操作的文章,
引言
有时我们总是希望我们的 Web 应用程序像桌面应用程序一样工作。我们受到 Google 地图或 local.live.com 的影响。我有一些关于这些东西如何工作的发现。该过程很有趣,因为它包括通过鼠标事件在 UI 上动态加载信息。我不想使用组件,也希望有同样的精度。图像缩放、平移是繁琐的任务,因为它们在 WinForm 上比在 Web 界面上更容易执行。但随着 Web 2.0 的发展,用户变得更加挑剔,开发者需要更多地在他们的思想上工作。最后,随着 Web 的变化,我们的应用程序也在变化。
使用代码
通过添加像素来缩放图像会激怒用户。同样,在响应流中的鼠标事件上渲染图像内容会导致服务器 RAM 负担过重,并容易导致内存泄漏和服务器崩溃。因此,最终为了给用户提供界面的灵活性和极快的速度,我们有很多方法。任何此类缩放或平移功能都有两个部分。
在 UI 中,我可以采用以下任何一种方式。
后端:图像操作。
首先,任何大小的图像都将重叠在正方形框上。对于任何图像,高度/宽度的值乘以 2,直到高度和宽度相同。
// e.g. Image Height:3000px
// Width 2400px
int sHeight = 1, sWidth = 1;
While (sWidth < 2400 || sHeight < 3000)
{
sHeight = sHeight * 2;
sWidth = sWidth * 2;
}
所以最后我们准备好了一个正方形图像,原始图像位于中心。现在是时候将整个图像分成瓦片,每个瓦片的大小都相同。这个小图像部分(瓦片)将在鼠标事件上呈现。裁剪图像的过程需要特殊的数学计算。
裁剪过程。
第一次,图像大小将是全尺寸,缩放级别为 1,象限坐标为 0, 0。所以结果将是 4 块,每块的大小都相同,a) 将每块分成进一步的 4 个大小相等的正方形。按照过程 (a),直到每一块都等于您最小的瓦片 [我取了 255 PX]。每次您调用重复过程来分割图像时,将缩放级别 + 1 并移动象限坐标。所以你会有- 左上 (0,0)
- 右上 (0,1)
- 左下 (1,0)
- 右下 (1,1)
imgTopLeft = SubDivide(objImg, Level + 1, Quadrant0 * 2 + 0,
Quadrant1 * 2 + 0);
imgTopRight = SubDivide(objImg, Level + 1, Quadrant0 * 2 + 0,
Quadrant1 * 2 + 1);
imgBottomLeft = SubDivide(objImg, Level + 1, Quadrant0 * 2 + 1,
Quadrant1 * 2 + 0);
imgBottomRight = SubDivide(objImg, Level + 1, Quadrant0 * 2 + 1,
Quadrant1 * 2 + 1);
继续通过以下方式保存您的每个正方形
dGraphics.DrawImage(imgTopLeft, new Rectangle(0, 0, Size[0], Size[1]),
0, 0, imgTopLeft.Width, imgTopLeft.Height, GraphicsUnit.Pixel);
dGraphics.DrawImage(imgTopRight, new Rectangle(0, Size[1], Size[0],
Size[1]), 0, 0, imgTopRight.Width,
imgTopRight.Height, GraphicsUnit.Pixel);
dGraphics.DrawImage(imgBottomLeft, new Rectangle(Size[0], 0, Size[0],
Size[1]), 0, 0, imgBottomLeft.Width, imgBottomLeft.Height,
GraphicsUnit.Pixel);
dGraphics.DrawImage(imgBottomRight, new Rectangle(Size[0], Size[1],
Size[0], Size[1]), 0, 0, imgBottomRight.Width,
imgBottomRight.Height, GraphicsUnit.Pixel);
还有一件事,我们需要确保我们的缩放级别不超过比例级别。因此,对于生成最后一个正方形,我们需要执行此检查。
int Scale = Convert.ToInt32(System.Math.Pow(2, Level));
int[] InverseSize ={ (objBmp.Width) / (Size[0] * Scale),
(objBmp.Height) / (Size[1] * Scale) };
int[] TopLeft ={ Quadrant0 * Size[0] * InverseSize[0],
Quadrant1 * Size[1] * InverseSize[1] };
int[] BottomRight = { TopLeft[0] + (Size[0] * InverseSize[0]),
TopLeft[1] + (Size[1] * InverseSize[1]) };
if (InverseSize[0] < 1.0 || InverseSize[1] < 1.0)
{
throw new Exception("Requested zoom Level is too high");
}
最后,我们有大量图像在每个级别都被裁剪成完美的正方形。此外,对于裁剪图像的命名约定有一个通用格式。如果它保存在 [Level]-[Quadrant0]-[Quadrant1].jpg 中,它将被不同的渲染 UI 组件(如 Zoomify 或 GAV)支持。我使用了图像编码器和压缩器来进行图像平滑处理。您可以传递图像的质量级别并获得您想要的图像。
关注点
所以我们现在有了一个带有深度计算过程的图像缩放器。只是简单的数学。希望你喜欢它。