Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Image Zooming,Chopping and Panning in ASP.net,C# like Google Maps.

0.00/5 (No votes)
26 Dec 2006 1  
An article on image operations giving user power of win forms

Sample Image - Web_Image_Operations.gif

Introduction

Sometime we always want our web applications to work as desktop application. We are influenced by Google maps or local.live.com. I have some findings how these stuff works. The process is interesting as it includes dynamic loading of information on UI through mouse events. I do not want to go for components and also want same precision. Image zooming, panning are tedious tasks as they are easy to perform on win forms rather that web interfaces. But as Web 2.0 grows, user gets more spoiled and developers need more to work on their minds. Finally, as web changes, our application too.

Using the code

Zooming image by adding pixels will irritate users. Again Rendering image content on mouse events in Response streams will cause Server RAM to extremely heavy loaded and exposed to memory leaks and server crashes. So finally giving users the flexibility of interface and extreme speed we have many ways. There are 2 parts of any such zooming or panning functionality.

Front End: UI.
In UI,I can for any of belowing ways.
1) Using Flash Component Zoomify.

Zoomify

2) Using GVIS.

GVIS


Back End: Image Manipulations.
First of all, image of any size will be overlapped on square box. For any image, value of Height/Width is multiplied with 2 till both height and width becomes same.
// e.g.       Image Height:3000px

//            Width 2400px


int sHeight = 1, sWidth = 1;
While (sWidth < 2400 || sHeight < 3000)
{
    sHeight = sHeight * 2;
    sWidth = sWidth * 2;
}

So finally we are prepared with square image, with original image in center. Now its time to divide entire image in tile, each of uniform size. This small image part as tile will be rendered on mouse events. Process of chopping image requires special mathematical calculation.

Chopping Process.

For first time, Image size will be full size, Zoom level be 1, and quadrant co- ordinates will be 0, 0. So result will be 4 pieces, each of uniform size, a) Take each part and divide into further 4 equal squares of uniform size. Follow process (a) until each piece becomes equal to your smallest tile [I took 255 PX]. Every time you call repetitive process to divide images, increase zoom level + 1 and shift quadrant co-ordinates.So you will have:

  1. Top-Left (0,0)
  2. Top-Right (0,1)
  3. Bottom-Left (1,0)
  4. Bottom-Right (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);

Continue to save your each square through

    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);

One more thing,we need to make sure that our zoom level should not exceed scale level. So,for generation of last square we need to perform this check.

    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");
    }

Finally we have large number of images that are chopped in perfect squares at every level. Also, there is common format for naming convention for chopped images. If its saved in [Level]-[Quadrant0]-[Quadrant1].jpg, it will be supported by different rendering UI components like Zoomify or GAV. I have used Image encoders and compressors for image soothing. You can pass quality level for image and get it your desired one.

Points of Interest

So we are now with image zoomifier with indepth process of calculations.Just simple maths.Hope you enjoyed it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here