Web Development

Watermark your images with this VB.NET code

Watermarking is a useful technique for branding or copyrighting images, and with a little bit of code, you can handle the task dynamically. Justin James explains how to create a watermark class that creates a watermark on a source image using either another image or text--and he's thrown in a watermarking application, complete with full source code and the class file, so you can see it in action.

Image watermarking is a technique for applying text or an image over another image in such a way that the overlay transforms the base image. It is often used for branding or copyright purposes, because removing the watermark is a difficult task, requiring a good deal of graphics editing by hand. Unfortunately, the Microsoft .NET Framework doesn't contain any built-in functionality for performing image watermarking dynamically. To compensate for this shortcoming, we'll construct a class that creates a watermark on a source image using either another image or text. Figure A and Figure B show two examples of watermarked images, one using text and one using an image.

Figure A

 

Figure B

 

You will note that watermarking isn't very effective in dark sections of the image. With dark images, a text halo is probably better. For information and source code for creating halos, see "Make your text stand out by adding a halo with this VB.NET code."

Watermark technique

Our watermark class will have a number of properties that determine where the watermark will be located on the source image, what type of watermark it is (text or image), and the exact watermark information. To begin with, we'll need a utility class with enumerations for the watermark type and location (Listing A).

Once we have this class, we can construct the watermark class. For text watermarks, we need to know what text to use and what font to create the watermark with. For image watermarks, we require a filename to the watermark image. For both kinds of watermarks, we require the original image file's filename and the location for the watermark. The main function to create the watermarked image requires no arguments, since all of the information it needs should have been set in properties. It returns an instance of the System.Drawing.Bitmap type.

The nature of this function makes it ideal for use in multithreaded situations. Depending upon the source image and watermark, watermarking can take a fair amount of CPU time. So it's sometimes better to perform it in the background and allow the main program to continue execution in the foreground. This is especially important if the watermarking process is part of a Web site. For example, if the site allows users to upload photos that should be watermarked, it's preferable to continue processing the rest of the page and check to make sure that the watermark was created than to hold up the whole page display waiting for the watermark to be created.

The watermark process is fairly simple. First, we create an overlay image the same size as the original, with the watermark in the desired location. The watermark is either loaded from an image or dynamically created with the desired font and text. Then, we look over the overlay image, searching for any pixels with color, indicated by the alpha channel value of that pixel. When we find a pixel with color, we use its brightness value to create a multiplier. The multiplier system, while a bit slower, allows the watermark to alter the base image differently based upon the shade of color used in an image watermark. It also allows us to have the potential of providing "watermark intensity" adjustments in the future, either by editing the source code or by providing a mechanism to pass the multiplier amount to the function.

Once we calculate the multiplier, we set the color of the original image at the same pixel location to its original color, but with the red, green, and blue channels multiplied by the multiplier. Because our multiplier is between 0 and 1, it will reduce the color saturation of the pixel, providing the watermark effect. Listing B contains the main processing code for the watermark process.

The line of code here of special notice is the one we use to create the pixel multiplier:

PixelMultiplier = 1 - CSng(((1 - WatermarkPixel.GetBrightness)) * 0.25)

Changing the final number (0.25) in this line adjusts the intensity of the watermark effect. At 0.25, it limits the range of saturation reduction to 0% to 25%. In other words, if the watermark image has pale shades of color, they won't watermark the original image much, if at all, and even the darkest colors will only perform a 25% reduction in color intensity on the original pixel colors. This number should never be below 0.0 (which will never watermark) or above 1.0 (which will make the watermark be white anywhere the watermark should appear). In my tests, I found that keeping this number from 0.2 to 0.3 yields the most pleasing results. Of course, it's possible to make this number a constant in the source code or edit the code to allow this number to be set at run time.

Try out the watermarking app

Programmatic watermarking can be useful for a dynamic Web site or for batch editing of images to meet your marketing needs. With this watermarking class, it's easy to incorporate these techniques into your application. The accompanying download installs a full application that produces watermarked images. The application's installer also copies the full source code for the application and the full class file for the image watermark. Feel free to try the code out yourself, incorporate it into your own project, and modify it to suit your needs.

About

Justin James is the Lead Architect for Conigent.

10 comments
rstringfield
rstringfield

Does not work. I tried using the code and it did nothing to my image. Then I tried running the compiled app, still nothing.

paulesc2003
paulesc2003

I think it is great however sometimes after I load a large file, over 221 meg, it will give me a out of memory error. Any ideas? Thanks It works fine now. It seems that if you put too large a file in the picture control this will happen. But, if you do the work behind the scenes and return a bitmap image, it works. Thanks

bbarnes
bbarnes

With the free download program IrfanView (www.irfanview.com) you can do all kinds of things to pictures and have the work finished before programs like Photoshop even open. This is an easy way to watermark photos and you can either do it to a single photo, or to a whole folder full of photos at once using its Batch Conversion/Rename capabilities. You can even set the text to be transparent. No scripts necessary.

JodyGilbert
JodyGilbert

Does this functionality help you fill in any missing pieces in your projects? What types of modifications will you make to the sample app?

amyhr
amyhr

Can it do it dynamically though? I think the big "selling" point of this free download is that it's a way to do it without opening an application. It's something that could be incorperated into a website such that marketing/graphics can have a set of photos and not have to watermark them before they go to the web, but the web server automatically watermarks them as they load using this method.

Justin James
Justin James

amyhr - That is enarly exactly what I was going to say, thanks! Yes, the previous poster is correct; there are tons of pieces of watermarking software out there already, or pieces of software capable of doing it in addition to other functionality. But as you say, the point here is to do it dynamically, on the fly, without firing up a whole application to do so. It is one thing to add another 5kb worth of library overhead to an existing .Net application or Web site; it is another thing to fire up a whole application and talk to it via OLE or COM, just for one simple function. J.Ja

bbarnes
bbarnes

This method watermarks single, or in batch, images before they are uploaded.

cleary_w
cleary_w

Thanks much for sharing your great work Justin. It runs but it does not add the watermark to a image though. I tried to run it from VS 2005 (F5) but still don't see the Text. Any help, please? And how can I add this for the web application using ASP.net, for example.

Justin James
Justin James

... it can be running on the server, and watermark as they are received. In fact, there are a dozen and one ways that you can use this (and similar) pieces of code. Here are some examples: * Tie it to an FTP server to be kicked off whenever certain file types are uploaded. * Run it within SQL Server on an UPDATE and INSERT trigger on a BLOB field (not that I recommend storing graphics in a database, mind you). * On a Web site, to watermark images as they are uploaded. * In an application to overlay helpful information. * As a modification to a game to display the time in the corner discretely, so the player can keep track of when it is time to go to bed (I think all games need this option anyways). These are just a few examples of how small code "widgets" that replicate existing application functionality can be used. Sure, if you build enough "widgets" that deal with the same datatype, you just need to glue them together to build a full application. But sometimes building an entire application is not the goal, just enhancing an existing one. :) The idea for this article actually came from the TechRepublic readership; I had written a similar article for text halos (based on some things I had done for a project involving adding data to maps), and a commenter pointed out that watermarks are often preferable to text halos. J.Ja

Editor's Picks