65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.20/5 (4投票s)

2006年12月26日

3分钟阅读

viewsIcon

51266

downloadIcon

2462

一篇关于图像操作的文章,赋予用户 Win Forms 的功能。

Sample Image - Web_Image_Operations.gif

引言

有时我们总是希望我们的 Web 应用程序像桌面应用程序一样工作。我们受到 Google 地图或 local.live.com 的影响。我有一些关于这些东西如何工作的发现。该过程很有趣,因为它包括通过鼠标事件在 UI 上动态加载信息。我不想使用组件,也希望有同样的精度。图像缩放、平移是繁琐的任务,因为它们在 WinForm 上比在 Web 界面上更容易执行。但随着 Web 2.0 的发展,用户变得更加挑剔,开发者需要更多地在他们的思想上工作。最后,随着 Web 的变化,我们的应用程序也在变化。

使用代码

通过添加像素来缩放图像会激怒用户。同样,在响应流中的鼠标事件上渲染图像内容会导致服务器 RAM 负担过重,并容易导致内存泄漏和服务器崩溃。因此,最终为了给用户提供界面的灵活性和极快的速度,我们有很多方法。任何此类缩放或平移功能都有两个部分。

前端:UI。
在 UI 中,我可以采用以下任何一种方式。
1) 使用 Flash 组件 Zoomify。

Zoomify

2) 使用 GVIS。

GVIS


后端:图像操作。
首先,任何大小的图像都将重叠在正方形框上。对于任何图像,高度/宽度的值乘以 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 并移动象限坐标。所以你会有

  1. 左上 (0,0)
  2. 右上 (0,1)
  3. 左下 (1,0)
  4. 右下 (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)支持。我使用了图像编码器和压缩器来进行图像平滑处理。您可以传递图像的质量级别并获得您想要的图像。

关注点

所以我们现在有了一个带有深度计算过程的图像缩放器。只是简单的数学。希望你喜欢它。

© . All rights reserved.