Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Dynamic DeepZoom ASP.NET User Control using Seadragon

, 19 May 2010 CPOL
A deepzoom user control doesn't need to generate deepzoom image files
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
using System.Net;
using IWshRuntimeLibrary;
    /// <summary>
    /// Summary description for GetTileImage
    /// </summary>
public class GetTileImage : IHttpHandler, IRequiresSessionState
{
    const string c_key = "dzi";

    public void ProcessRequest(HttpContext context)
    {
        //context.Response.Cache.SetMaxAge(TimeSpan.FromMinutes(60));
        WshShell sh = new WshShell();
        
        int level = int.Parse(context.Request["level"]);
        int x = int.Parse(context.Request["x"]);
        int y = int.Parse(context.Request["y"]);
        int tileSize = int.Parse(context.Request["tileSize"]);
        int tileOverlap = int.Parse(context.Request["tileOverlap"]);
        string imageUrl = context.Request["image"];

        Bitmap source = LoadImage(imageUrl);
        if (source == null)
            return;

        Bitmap tile = CreateTileImage(source, level, x, y, tileSize, tileOverlap);

        context.Response.ContentType = "image/jpeg";
        ImageCodecInfo[] icf = ImageCodecInfo.GetImageEncoders();
        EncoderParameters encps = new EncoderParameters(1);
        encps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 85L);
        //tile.Save(context.Response.OutputStream, icf[1], encps);
        foreach (ImageCodecInfo info in icf)
        {
            if (string.Compare(info.FormatDescription, "JPEG") == 0)
            {
                tile.Save(context.Response.OutputStream, info, encps);
                break;
            }
        }
    }

    public bool IsReusable
    {
        get
        {
            return true;
        }
    }

    Bitmap CreateTileImage(Bitmap source, int level, int x, int y, int tileSize, int tileOverlap)
    {
        int width, height;
        if (source.Width > source.Height)
        {
            width = (int)Math.Pow(2, level);
            height = width * source.Height / source.Width;
        }
        else
        {
            height = (int)Math.Pow(2, level);
            width = height * source.Width / source.Height;
        }
        tileSize = Math.Min(tileSize, (int)Math.Pow(2, level));
        int tileLeft = x * tileSize - tileOverlap;
        int tileWidth = tileSize + 2 * tileOverlap;
        int tileTop = y * tileSize - tileOverlap;
        int tileHeight = tileSize + 2 * tileOverlap;
        if (tileLeft < 0)
        {
            tileLeft += tileOverlap;
            tileWidth -= tileOverlap;
        }
        if (tileTop < 0)
        {
            tileTop += tileOverlap;
            tileHeight -= tileOverlap;
        }

        float ratio = (float)source.Width / width;
        float srcLeft = tileLeft * ratio;
        float srcWidth = tileWidth * ratio;
        float srcTop = tileTop * ratio;
        float srcHeight = tileHeight * ratio;
        if (srcLeft + srcWidth > source.Width)
        {
            srcWidth = source.Width - srcLeft;
            tileWidth = (int)Math.Round(srcWidth / ratio);
        }
        if (srcTop + srcHeight > source.Height)
        {
            srcHeight = source.Height - srcTop;
            tileHeight = (int)Math.Round(srcHeight / ratio);
        }

        Bitmap bmp = new Bitmap(tileWidth, tileHeight);
        Graphics g = Graphics.FromImage(bmp);
        g.InterpolationMode = InterpolationMode.HighQualityBicubic; 
        g.DrawImage(source,
            new RectangleF(0, 0, tileWidth, tileHeight),
            new RectangleF(srcLeft, srcTop, srcWidth, srcHeight),
            GraphicsUnit.Pixel);
        g.Dispose();
        return bmp;
    }

    public static Bitmap LoadImage(string imageUrl)
    {
        Dictionary<string, Bitmap> images = (Dictionary<string, Bitmap>)HttpContext.Current.Session[c_key];
        if (images == null)
        {
            images = new Dictionary<string, Bitmap>();
            HttpContext.Current.Session[c_key] = images;
        }
        Bitmap bmp = null;
        if (!images.ContainsKey(imageUrl))
        {
            try
            {
                string url = imageUrl;
                if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
                    url = HttpContext.Current.Server.MapPath(url);

                WebClient wc = new WebClient();
                Stream fs = wc.OpenRead(url);
                bmp = new Bitmap(fs);
                fs.Close();
            }
            catch { return null; }
        }
        else
        {
            bmp = images[imageUrl];
            images.Remove(imageUrl);
            Dictionary<string, Bitmap> tmp = new Dictionary<string, Bitmap>();
            foreach (string key in images.Keys)
                tmp.Add(key, images[key]);
            images = tmp;
            HttpContext.Current.Session[c_key] = images;
        }
        images.Add(imageUrl, bmp);
        if (images.Count > 5)
        {
            Dictionary<string, Bitmap>.KeyCollection.Enumerator e = images.Keys.GetEnumerator();
            e.MoveNext();
            string key = e.Current;
            images.Remove(key);
        }
        return bmp;
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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

Share

About the Author

Lang Deng
Web Developer
United States United States
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150129.1 | Last Updated 20 May 2010
Article Copyright 2010 by Lang Deng
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid