Dynamically watermark a picture in a ASP.NET page
In a previous post, I’ve explain how to use generic ASP.NET handlers to display a picture. The concept is easy to use and perfect to manipulate any kind of document you want to output in your web server. There equivalent of this in technologies like PHP or Java but it’s so easy to do using ASP.NET. In my previous post, I’ve used VB, so I’ll continue with VB Don’t worry, it’s as easy to do in C#!
The overall code to watermark an image dynamically using the generic handler and the minimum manipulation code is here:
<%@ WebHandler Language="VB" Class="Image" %>
Imports System
Imports System.Web
Imports System.Net
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Drawing2D
Public Class Image : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.ContentType = "image/jpeg"
context.Response.AddHeader("Cache-Control", "private,must-revalidate,post-check=1,pre-check=2,no-cache")
Dim instanceHTTP As New WebClient
Dim MaCamera As New Camera
Dim MyUri As New Uri("file://c:/Temp/image.jpg")
Dim returnValue As Stream
Try
returnValue = instanceHTTP.OpenRead(MyUri)
Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)
Dim MyText As String = Now.ToString("yyy-MM-dd HH-mm")
Dim MyGraphics As Graphics = Graphics.FromImage(MyImage)
Dim MyFont As Font = New Font(FontFamily.GenericSerif, 12)
MyGraphics.DrawString(MyText, MyFont, Brushes.White, 100, 100)
MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
MyGraphics.Dispose()
MyImage.Dispose()
Catch ex As Exception
context.Response.Write("Error")
End Try
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
I will not explain again what I’ve explain in the previous post on the way handlers are working. So I’ll just concentrate on the image manipulation and how to write text in an image dynamically.
returnValue = instanceHTTP.OpenRead(MyUri)
Dim MyImage As System.Drawing.Image = System.Drawing.Image.FromStream(returnValue)
Dim MyText As String = Now.ToString("yyy-MM-dd HH-mm")
Dim MyGraphics As Graphics = Graphics.FromImage(MyImage)
Dim MyFont As Font = New Font(FontFamily.GenericSerif, 12)
MyGraphics.DrawString(MyText, MyFont, Brushes.White, 100, 100)
MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
MyGraphics.Dispose()
MyImage.Dispose()
I first open a URI which contains an image. In my case a static image sitting on the hard drive but the idea here is to take it from a webcam for example. The URI is open as a stream and passed to an Image object.
The idea here is to watermark the image with the date. So I create a simple string containing the date and time in a dedicated formatting. I like this formatting "yyy-MM-dd HH-mm" as it’s easy to sort especially with files. It does return a text like “2011-11-24 10-47”.
Then I create a graphics object pointing on the image. This object is directly link to the image we have loaded and any modification made on the graphics object will impact the image. It’s the basic concept of pointers used here.
In order to write text, you’ll have to choose a font. Again, nothing complicated here, choose your preferred font and the size. A good Serif and a 12 size will be enough in my example.
And let the magic work using the DrawString method to draw in the graphics, so in the image your text. The 100 and 100 params are the X and Y starting point where to write the text. It starts on the upper left corner of the image. You can also use predefined points. But for the example, I keep it very simple.
And as explain in the previous post, you just have to save your watermarked picture into the output stream and you’re done. Or almost done, don’t forget to dispose the graphics objects, better to do it especially if you want to scale up. The garbage collector will thank you
Final result will look like that:
And of course, you can do more, much more using this handler. You can add shapes, transform the color schemas, apply filters, etc. .NET is full or very efficient graphics manipulations. so just use them! In my case I use it to tag pictures with date and time as in this example but also to control when I can access an image on some webcam. I do not expose them directly to the web. They are only accessible thru handlers like this. And only to specific persons (with a login and password) and on specific time. Maybe more in a next example!
As always, feedback welcome The code and blog post written in a plane from Paris to Zagreb
Comments
Anonymous
July 12, 2015
Hello. I've been searching for image watermark like this and I think that this post is the most closest from what I want and the post and code that I really understand the most. I already have the HTTPHandler to output my image from database on-the-fly. However, as other posts that I've read, all post using text as watermark. It is possible to use image or logo to watermark the original image rather than using text as watermark? I already search your blog and no result for watermark other than this. If possible, how to do that? I really hope your feedback. Thanks.Anonymous
July 12, 2015
Hello. I've been searching for image watermark like this and I think that this post is the most closest from what I want and the post and code that I really understand the most. I already have the HTTPHandler to output my image from database on-the-fly. However, as other posts that I've read, all post using text as watermark. It is possible to use image or logo to watermark the original image rather than using text as watermark? I already search your blog and no result for watermark other than this. If possible, how to do that? I really hope your feedback. Thanks.