Click here to Skip to main content
Licence CPOL
First Posted 11 Apr 2007
Views 28,896
Downloads 207
Bookmarked 22 times

Zoom an image in ASP.NET with GDI+ using Bitmap's OutStream option

By | 11 Apr 2007 | Article
Image manipulation in ASP.NET including zooming, drawing lines, etc., using GDI+.

Screenshot - zoomsmall2.jpg

Introduction

This article will show you how to do image manipulation in ASP.NET, like zooming, drawing lines etc.

Background

Using the Bitmap class' Save method with Response.OutStream is the underlying way to output images to a page. The problem is that it will redirect you to a blank page. This code solves that problem by setting an image button's image URL as an ASPX URL that outputs to the stream.

Using the Code

The following snippet is the heart of the operation. This snippet resides in our ASPX page that we will use as the URL image of our image button. We have the following code which grabs some parameters passed in through the query string and a few through the session (this is not a great way to do this, but this is only a quic k demo).

Then, it will take a look at where the user clicked and create a region around that based on a zoom level. It will then grab a smaller source rect and draw it to the destination. It will then output it to the stream, which is ImageButton1 in page ZoomZoom.

Once you have the Graphics object, you are able to draw lines or whatever you wish, so you can do anything GDI+ allows.

protected void Page_Load(object sender, EventArgs e)
{
   Mouse mouse = (Mouse)Session[Mouse.SessionName];

   ImageViewParameters Pageparams = 
     (ImageViewParameters)Session[ImageViewParameters.SessionName];

   if (mouse == null || Pageparams == null )
   {
      Server.Transfer("Zoomzoom.aspx");
   }

   string loc = Request.QueryString[PageVariables.ImagePath].ToString();
   // this.ImageButton1.ImageUrl.Replace("~", "");

   if (loc == null)
   { 
      return;
   }

   if (loc.Length < 5)
   {
      return;
   }

   Bitmap bitmap = new Bitmap(loc);

   MouseToImageCoordinates(mouse, Pageparams, bitmap);
   // Dimentions of the zoomed square
   float squareSizeX = (int)( (float)bitmap.Width / (float)Pageparams.ZoomLevel );
   float squareSizeY = (int)((float) bitmap.Height / (float)Pageparams.ZoomLevel );
   // Create a new bitmap which we will draw on
   Bitmap bitmap2 = new Bitmap(bitmap.Width, bitmap.Height);
   // Get the graphics device from the blank image
   Graphics g = Graphics.FromImage( bitmap2 );
   // Make a rect around where the user clicked
   float desX = ( mouse.X - (squareSizeX / 2.0f) ) ;
   float desY = ( mouse.Y - (squareSizeY / 2.0f) );

   RectangleF source = new RectangleF(desX, desY, squareSizeX, squareSizeY);
   RectangleF destination = new RectangleF(0, 0, bitmap.Width, bitmap.Height);

   g.DrawImage(bitmap, destination, source, GraphicsUnit.Pixel);
   // Output the image to the stream
   bitmap2.Save(Response.OutputStream, ImageFormat.Jpeg);

}

Enhancements

  1. The first image at the top navigates where the user clicks, but it might be better if it worked more like the Windows image viewer. I did it that way at first, but it was too slow to get to the farthest zoom level, and would cause needless server utilization. I would recommend drawing a box in the navigation image showing the viewable portion of the zoomed in image below. (Just draw the source rect of the zoomed image on the other image.)
  2. If you click on the edge, it sometimes shows black in a low zoom level.

Points of Interest

I did spend quite some time researching the best way to do this, but not much time on the code. A few things to watch out for: it will probably hammer the server's CPU pretty good, so I'm not sure how many users can view the page at once.

Alternatives

I also tried embedding a Windows Forms control into a webpage which does work (Google for Andrew Ma's articles) without the user having to do anything; however, it seemed like sometimes the user might get a blank box depending on how the security was set up. It also felt really hackish. If the zone was not trusted, then no errors are reported, it just doesn't work. The other way to do this would be an ActiveX control, but then again, you have security issues and upgrade issues. I also viewed a bunch of AJAX samples, but they also run fairly slow (at least, the ones I saw). The AJAX samples didn't run faster than this, but IIS is on my machine with just one user, so that's not a fair test.

This is the best way I have seen this done from a deployment perspective .

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

rj45

Software Developer (Senior)

Canada Canada

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralError could not load type ASPImaging.Global Pinmemberkarti20:17 1 Apr '08  
While running the zoom file i have an error Error Could Not Load Type ASPImaging.Global.
 
Could any one help me to get out of my error please.
Generalscreen shots PinmemberSacha Barber1:16 12 Apr '07  
GeneralRe: screen shots Pinmemberrj458:32 12 Apr '07  
GeneralRe: screen shots Pinmemberrj458:32 12 Apr '07  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120529.1 | Last Updated 11 Apr 2007
Article Copyright 2007 by rj45
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid