Zoom an image in asp_net with GDI+ using Bitmaps's OutStream option
IntroductionThis will show you how to do image manipulation in asp.net. ie zooming , drawing lines.
Background
Using the bitmap class's save 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 solves that problem by setting an imagebutton's image url as an aspx url that outputs to the stream.
Using the code
The following snippit is the heart of the operation. This snippit resides in our aspx page that we will use as the urlImage of our imagebutton. 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 quick 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 the GDI+ allows.
Collapse
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);
}
Enchancements
1)The first image at the top navagates where the user is clicked, but it might be better if it worked more like 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 navagation 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 ebst 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 form control into a webpage which does work ( google 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 one user so thats not a fair test.
This is the best way I have seen this done from a deployment persective .

0 Comments:
Post a Comment
<< Home