Solved

Watermark or Image Overlay using HttpHandler

Posted on 2008-06-25
4
4,028 Views
Last Modified: 2012-06-27
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

0
Comment
Question by:Nugs
  • 2
  • 2
4 Comments
 
LVL 18

Expert Comment

by:jcoehoorn
ID: 21868499
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
 
LVL 2

Accepted Solution

by:
Nugs earned 0 total points
ID: 21868536
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
 
LVL 18

Expert Comment

by:jcoehoorn
ID: 21868766
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
 
LVL 2

Author Comment

by:Nugs
ID: 21868823
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

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…
As a trusted technology advisor to your customers you are likely getting the daily question of, ‘should I put this in the cloud?’ As customer demands for cloud services increases, companies will see a shift from traditional buying patterns to new…

896 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now