Watermark or Image Overlay using HttpHandler

Morning guys and gals,

I have an e-commerce website that displays product images using a HTTPHandler (for resizing) I have been looking for a way to overlay "Coming Soon" on top of the image for products that were not yet available for purchase...

I found a really cool little article by Donn Felker for a HTTPHandler that does this... http://blog.donnfelker.com/2007/09/18/WatermarkingImagesInASPNETWithAnHttpHandler.aspx 

His is slightly different where his code watermarks all images, i want to add a similar method to my HTTPHandler that if run will overlay the image with whatever....

Can someone maybe help me with this as i am not sure how to adapt this code to function in this way.

Attchaed is my HTTPHandler

Nugs
<%@ WebHandler Language="C#" Class="ImageHandler" %>
 
using System;
using System.Web;
using System.IO;
using System.Drawing;
using ClassLib.Utility_Libraries;
using ClassLib.Logging_Libraries;
 
public class ImageHandler : IHttpHandler
{   
    public void ProcessRequest(HttpContext context)
    {
        string Filepath = context.Request["Filename"];
        string ImgHeight = context.Request["Height"];
        string ImgWidth = context.Request["Width"];       
 
        CreateJpegThumb(Filepath, ImgHeight, ImgWidth);
    }
 
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
 
    public static void CreateJpegThumb(string relativeFileName, string ImageHeight, string ImageWidth)
    {
        try
        {
            double xImgHeight = Convert.ToDouble(ImageHeight);
            double xImgWidth = Convert.ToDouble(ImageWidth);
 
            string[] pathnodes = HttpContext.Current.Request.Path.Split('/');
            string rightnode = pathnodes[pathnodes.Length - 1];
 
            ImageManager ImgManager = new ImageManager();
            string file = ImgManager.GetServerPath + "\\" + relativeFileName.Replace('/', '\\').Trim();
 
            System.Drawing.Image oImg = null;
            oImg = System.Drawing.Image.FromFile(file);
 
            System.Drawing.Image Resized = ResizeJpeg(oImg, xImgWidth, xImgHeight);
 
            MemoryStream imageStream = new MemoryStream();
            Resized.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] imageContent = new Byte[imageStream.Length];
            imageStream.Position = 0;
            imageStream.Read(imageContent, 0, (int)imageStream.Length);
 
            HttpContext.Current.Response.ContentType = "image/jpeg";
            HttpContext.Current.Response.BinaryWrite(imageContent);
            Resized.Dispose();
            oImg.Dispose();
        }
        catch (Exception exc)
        {
            ErrorReporter ReportError = new ErrorReporter("Thenga_ImageHandler.ashx", 60);
            ReportError.LogExc(exc);
        }
    }
 
    public static System.Drawing.Image ResizeJpeg(System.Drawing.Image Original, double MaxWidth, double MaxHeight)
    {
        double width;
        double height;
        width = Math.Min(MaxWidth, Original.Width);
        double tempMultiplier = width / Original.Width;
        if (tempMultiplier > 1.0)
        {
            tempMultiplier = 1.0;
        }
        
        height = Original.Height * tempMultiplier;
        System.Drawing.Image Resized = new Bitmap(Convert.ToInt32(width), Convert.ToInt32(height), Original.PixelFormat);
 
        Graphics oGraphic = Graphics.FromImage(Resized);
        Rectangle oRectangle = new Rectangle(0, 0, Convert.ToInt32(width), Convert.ToInt32(height));
        oGraphic.DrawImage(Original, oRectangle);
 
        return Resized;
    }
}

Open in new window

LVL 2
NugsAsked:
Who is Participating?
 
NugsAuthor Commented:
I managed to get this working... Pretty neat....

jcoehoorn: The reason i want to do this is to have the flexibility to overlay whatever text i wish. "Coming Soon" or "Sold" or whatever... And in terms of the processing, well out of 100 product image, 1 of those products may be "coming soon" or require the watermark... I think it will be worth the server load.

Nugs
<%@ WebHandler Language="C#" Class="ImageHandler" %>
 
using System;
using System.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using ClassLib.Utility_Libraries;
using ClassLib.Logging_Libraries;
 
public class ImageHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        string Filepath = context.Request["Filename"];
        string ImgHeight = context.Request["Height"];
        string ImgWidth = context.Request["Width"];
 
        CreateJpegThumb(Filepath, ImgHeight, ImgWidth);
    }
 
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
 
    public static void CreateJpegThumb(string relativeFileName, string ImageHeight, string ImageWidth)
    {
        try
        {
            double xImgHeight = Convert.ToDouble(ImageHeight);
            double xImgWidth = Convert.ToDouble(ImageWidth);
 
            string[] pathnodes = HttpContext.Current.Request.Path.Split('/');
            string rightnode = pathnodes[pathnodes.Length - 1];
 
            ImageManager ImgManager = new ImageManager();
            string file = ImgManager.GetServerPath + "\\" + relativeFileName.Replace('/', '\\').Trim();
 
            System.Drawing.Image oImg = null;
            oImg = System.Drawing.Image.FromFile(file);
 
            System.Drawing.Image Resized = ResizeJpeg(oImg, xImgWidth, xImgHeight);
            
            //JUST NEED TO ADD SOMETHING HERE TO TELL IF IT MUST BE WATERMARKED OR NOT!
            //-------------------------------------------------------------------------
            System.Drawing.Image Resized2 = WatermarkImage(Resized, "Coming Soon");
 
            MemoryStream imageStream = new MemoryStream();
            Resized2.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] imageContent = new Byte[imageStream.Length];
            imageStream.Position = 0;
            imageStream.Read(imageContent, 0, (int)imageStream.Length);
 
            HttpContext.Current.Response.ContentType = "image/jpeg";
            HttpContext.Current.Response.BinaryWrite(imageContent);
            Resized.Dispose();
            oImg.Dispose();
        }
        catch (Exception exc)
        {
            ErrorReporter ReportError = new ErrorReporter("Thenga_ImageHandler.ashx", 60);
            ReportError.LogExc(exc);
        }
    }
 
    public static System.Drawing.Image ResizeJpeg(System.Drawing.Image Original, double MaxWidth, double MaxHeight)
    {
        double width;
        double height;
        width = Math.Min(MaxWidth, Original.Width);
        double tempMultiplier = width / Original.Width;
        if (tempMultiplier > 1.0)
        {
            tempMultiplier = 1.0;
        }
 
        height = Original.Height * tempMultiplier;
        System.Drawing.Image Resized = new Bitmap(Convert.ToInt32(width), Convert.ToInt32(height), Original.PixelFormat);
 
        Graphics oGraphic = Graphics.FromImage(Resized);
        Rectangle oRectangle = new Rectangle(0, 0, Convert.ToInt32(width), Convert.ToInt32(height));
        oGraphic.DrawImage(Original, oRectangle);
 
        return Resized;
    }
 
    protected static System.Drawing.Image WatermarkImage(System.Drawing.Image image, string watermark)
    {
        Graphics graphic;
        if (image.PixelFormat != PixelFormat.Indexed && image.PixelFormat != PixelFormat.Format8bppIndexed && image.PixelFormat != PixelFormat.Format4bppIndexed && image.PixelFormat != PixelFormat.Format1bppIndexed)
        {
            // Graphic is not a Indexed (GIF) image
            graphic = Graphics.FromImage(image);
        }
        else
        {
            /* Cannot create a graphics object from an indexed (GIF) image. 
             * So we're going to copy the image into a new bitmap so 
             * we can work with it. */
            Bitmap indexedImage = new Bitmap(image);
            graphic = Graphics.FromImage(indexedImage);
 
            // Draw the contents of the original bitmap onto the new bitmap. 
            graphic.DrawImage(image, 0, 0, image.Width, image.Height);
            image = indexedImage;
        }
        graphic.SmoothingMode = SmoothingMode.AntiAlias & SmoothingMode.HighQuality;
 
        Font myFont = new Font("Arial", 15);
        SolidBrush brush = new SolidBrush(Color.FromArgb(80, Color.White));
 
        /* This gets the size of the graphic so we can determine 
         * the loop counts and placement of the watermarked text. */
        SizeF textSize = graphic.MeasureString(watermark, myFont);
 
        // Write the text across the image. 
        for (int y = 0; y < image.Height; y++)
        {
            for (int x = 0; x < image.Width; x++)
            {
                PointF pointF = new PointF(x, y);
                graphic.DrawString(watermark, myFont, brush, pointF);
                x += Convert.ToInt32(textSize.Width);
            }
            y += Convert.ToInt32(textSize.Height);
        }
 
        //using (MemoryStream memoryStream = new MemoryStream())
        //{
        //    image.Save(memoryStream, GetImageFormat(context.Request.PhysicalPath));
        //}
        
        return image;
    }
}

Open in new window

0
 
Joel CoehoornDirector of Information TechnologyCommented:
That'll take a lot of processing on the part of your server.  Much simpler to just a layer a span tag over top of the image and let the browser do most of the work.
0
 
Joel CoehoornDirector of Information TechnologyCommented:
A span tag (asp.net label control) would give you the same flexibility, but if you have this working that's pretty cool too.  
0
 
NugsAuthor Commented:
I guess by flexibility i also mean i am lazy and i want the implementing of this to be easy... All my product images use this HTTPHandler, by modifying this to handle that watermarking the change will be implemented site wide. If i used a span or div with a transparent gif or png over the images i will need to implement this wherever an image is displayed and the code to turn it on or off...
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.