Search code examples
asp.netimagewatermark

Add watermarktext to image dynamically without saving image to server


I have an image stored on my server in this folder: \images\freemedia\largethumbs\test.png

On my default.aspx page I have an imagecontrol:

<asp:Image ID="Image1" runat="server" />

When the visitor requests the default.aspx page I want to get the test.png image from the server, add the watermark text "hello world" to it on the right bottom. I DON'T want to save the watermarked image to the server, since I want to save storage and still want to have access to the original image. From the image that is shown to the visitor, he should preferably not be able to derive the original filename, so he should not be allowed to see that the original filename is test.png.

I've been searching on Google a lot, but all examples save the watermarked image to disk, which I don't want.

I already have a httphandler:

Public Class pichandler : Implements IHttpHandler

Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
    Dim data As Byte()
    Dim fName As String 

    Using w As New generaltablesTableAdapters.freemediaTableAdapter
        fName = w.GetDataById(i)(0).medialink.ToString
    End Using
    data = My.Computer.FileSystem.ReadAllBytes(context.Server.MapPath("~/images/freemedia/thumbs/" & fName))

    ' --> how can I add a watermark text to the image here?!?!?!?

    context.Response.ContentType = "image/jpeg"
    context.Response.BinaryWrite(data)
End Sub


End Class

Does anyone have a code sample on how to do this?

If there's another way of doing this, that is fine too. But please show how I can serve the watermarked image as part of the final HTML.


Solution

  • Since you are working with asp.net, you might as well use an HttpHandler.

    Here's an example, create a new generic handler, let's call it ImageHandler and the code can be as easy as this:

    public class ImageHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            // Clear response and set content type to image.
            context.Response.Clear();
            context.Response.ContentType = "image/jpeg";
    
            // Create your image, however you want it. Server.MapPath and so on.
            var image = Bitmap.FromFile(@"C:\Images\image.jpg");
    
            // And save it to the OutputStream.
            image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
        }
    
        public bool IsReusable
        {
            get { return false; }
        }
    }
    

    And then just use it like this:

    <asp:Image ID="Image1" ImageUrl="~/ImageHandler.ashx" runat="server" />
    

    Of course you could also send in some QueryString parameters like this:

    <asp:Image ID="Image1" ImageUrl="~/ImageHandler.ashx?filename=myimage.jpg" runat="server" />
    

    And then just use context.Request.QueryString["filename"] in the ImageHandler.


    UPDATE:

    After the comments, here's how you can add a watermark:

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Dim watermarkText As String = "Copyright"
        Dim fName As String 
    
        Using w As New TopTrouwen.generaltablesTableAdapters.freemediaTableAdapter
            fName = w.GetDataById(i)(0).medialink.ToString
        End Using
    
        ' Create image directly from the path
        Dim image = Drawing.Image.FromFile(context.Server.MapPath("~/images/freemedia/thumbs/" & fName))
        Dim font As New Font("Tahoma", 16, FontStyle.Regular, GraphicsUnit.Pixel)
    
        'Adds a transparent watermark 
        Dim color As Color = Drawing.Color.FromArgb(50, 0, 0, 0)
        Dim brush As New SolidBrush(color)
        Dim gr As Graphics = Graphics.FromImage(image)
    
        ' Measure the watermark text so we can offset it's width and height
        Dim watermarkSize = gr.MeasureString(watermarkText, font)
    
        ' Create the point where the watermark text should be printed
        Dim point As New Point(image.Width - watermarkSize.Width, image.Height - watermarkSize.Height)
    
        gr.DrawString(watermarkText, font, brush, point)
        gr.Dispose()
    
        context.Response.ContentType = "image/jpeg"
        image.Save(context.Response.OutputStream, ImageFormat.Jpeg)
    End Sub