Click here to Skip to main content
15,867,308 members
Articles / Desktop Programming / MFC

WaterMarker

Rate me:
Please Sign up or sign in to vote.
4.75/5 (17 votes)
5 Apr 2006Zlib5 min read 103.5K   3K   64   32
An utility to protect yout pictures with a stamp bitmap.

00-Intro.png

Introduction

Some time ago, I started to create a little site about coding and hardware hacking on my hard drive. I took many pictures to document things, made thumbnails, and so. I then presented the result to a friend who spotted a problem about picture copyrights and stealing issues. He also had the same problem as a horse photographer. Pictures had to be water marked to prevent their stealing.

The problem to be solved

I then started to browse the web for a little utility that could watermark my pictures so that I could release my work with less fears. But it appeared that the only available tools were quite expensive for what they offered, in a range from $25 to $50! It just couldn't cost that much, it is just about some pixel blending, which has been available for ages, so where were the difficult problems that deserved such wages? I'm a coder, so I took the problem in my little hands...

Compilation

The Visual C++ 6 .dsw workspace file in the download contains all the projects. Just do a first Rebuild All to compile each project. Because some projects need lib/DLLs that will be compiled afterwards, you'll get some link error. Just wait for the first build session to finish, and then do a Build All to re-link everything once it has been compiled first. You may get some compile warnings in the CxImage project (Jasper), but this isn't a problem...

The quest for the right classes

Being quite regular on the CodeProject, I have some preferred classes that I reuse regularly. I know them well and modified some; here's the list of the ones I used:

  • CWnd Helper Class by Alvaro Mendez (modified): windows position saving/restore
  • CPathSplit by me: easily split a path
  • CDiskObject by Johan Rosengren: list files in a folder
  • CEditLabel by me (modified CStaticLabel from unknown author): edit path and change background color to warn user if something went wrong
  • GroupControl by Paul S. Vickery: disable some part of the UI as long as not all fields are correct
  • Some personal and private utility classes:

  • CSkinProgress by me: display the progress of the watermarking task
  • And the root engine of my utility, CxImage by Davide Pizzolato: basic and advanced image handling

Basic explanations of the stamp positioning algorithm

The stamping of an image needs only a few parameters. The relative position of the stamp from the image's corners, the relative displacement from the corner position, and a tiling option. The transparency of the stamp have also to be handled, coming from the original stamp if it supports alpha channel, or add one if the original stamp hasn't. Let's first analyse how CxImage handles pictures.

CxImage picture format

01-CxImage.png

The origin (hot spot) of CxImage is the bottom-left corner. X-axis is right-to-left, and Y-axis is top-to-down. When positioning a stamp at (0, 0), its location is on the bottom-left corner. The CxImage format can be called counter-Cartesian.

Positioning the stamp at the center of the image

02-Center.png

Due to the CxImage format, to center the stamp on the center of the image, you have to shift the stamp bottom-left from its half size to center its hot spot, then bring it back top-right from the image's half size, so that the centered stamp's hot spot is now located on the center of the image.

Positioning the stamp in the corners

03-Corner.png

To locate the stamp in a corner, we just have to shift it from the image center position of half of the size of the image minus half the size of the stamp. It will first edge the hot spot of the stamp, then bring it back in the image.

Relative shifting

04 - Relative.png

From its corner position, we can shift the stamp some more pixels. Just remember that the CxImage format is counter-Cartesian, so to shift right, you have to decrease the X-axis (increase to go shift left), and decrease again vertically if you want to shift the stamp up (increase to shift down).

Tiling the stamp

05 - Tiling.png

We can tile it all around the image, we just have to shift'n-loop the stamp several times of its size across the image relative to its calculated relative corner position. For this, calculate the start position and end position by dividing the image size by the stamp size. We will start for the lowest position (X and Y, that's to say, top-right) and increase each position up to the maximum CxImage formatted position (remember, counter-Cartesian, bottom-left). Be careful about the starting location. The initial shift is not the same when starting from the left corner than the right; again, not the same starting from the bottom corner than the top.

Managing some translucency

06 - Transludency.png

The PNG format is one of the best image formats. It doesn't compress photographic images well, but beats JPEG pictures on sketches and schematics with flat colours, which is enough for stamps. PNG is always lossless (unlike JPEG, that destroys the picture, even with a 100% quality factor), and includes an alpha layer. By using a PNG picture as stamp, you can nicely use its alpha channel to provide nice looking stamps. If you use another stamp format, you can also provide a flat alpha factor.

Image resizing

07 - Resizing.png

You can resize the input image at two locations: before watermarking, and after. By efficiently using these resize factors, you can make the stamp half its size (double the image before stamping, then reduce everything), or double it (reduce first, double after). It may also be quite interesting to release the stamped pictures in a more lightweight format than the original one, which is quite useful (leaving the original size before stamping, then reducing the result by 50%).

Problem solved

Here's the result of my little brainstorming. It's free, it's there, its source code is provided (so don't bug me about the French language, was too lazy to translate before submission). I'm not a UI master, so I recognize things can be improved in this area. But the purpose was just to provide me and my friend a free little watermarking utility that just performs well.

License

This code is thrown in the public domain, there's no secret coding recipe or tricks that might be patented. Commercial usage of this utility is prohibited ! I released it for free, so I expect any other derivative work to remain free as well. Also, please include the original or modified source code with explanations.

History

  • 1.02 06/04/05: First release, as is...

License

This article, along with any associated source code and files, is licensed under The zlib/libpng License


Written By
Software Developer
France France
KOCH David, 41 years old
Coder (embedded, C/C++, ASM, Erlang)

Comments and Discussions

 
Questionmy vote of 5 Pin
Michael Haephrati21-Jan-16 9:40
professionalMichael Haephrati21-Jan-16 9:40 
AnswerRe: my vote of 5 Pin
Kochise21-Jan-16 21:00
Kochise21-Jan-16 21:00 
Generaltext watermark Pin
xijun22-Apr-06 16:26
xijun22-Apr-06 16:26 
GeneralRe: text watermark Pin
Kochise23-Apr-06 9:41
Kochise23-Apr-06 9:41 
QuestionRe: text watermark Pin
Synetech10-Sep-06 20:48
Synetech10-Sep-06 20:48 
I take it that you mean the watermark will be some writing on the picture rather than a way to watermark a text file right?


--
Synetech

AnswerRe: text watermark Pin
Kochise10-Sep-06 21:11
Kochise10-Sep-06 21:11 
GeneralSorry, but like an typical french Pin
MGutmann11-Apr-06 0:01
MGutmann11-Apr-06 0:01 
GeneralRe: Sorry, but like an typical french Pin
Kochise11-Apr-06 8:57
Kochise11-Apr-06 8:57 
GeneralRe: Sorry, but like an typical french Pin
MGutmann11-Apr-06 20:04
MGutmann11-Apr-06 20:04 
GeneralRe: Sorry, but like an typical french Pin
Kochise11-Apr-06 22:26
Kochise11-Apr-06 22:26 
GeneralRe: Sorry, but like an typical french Pin
MGutmann11-Apr-06 23:01
MGutmann11-Apr-06 23:01 
GeneralRe: Sorry, but like an typical french Pin
Kochise11-Apr-06 23:34
Kochise11-Apr-06 23:34 
GeneralRe: Sorry, but like an typical french Pin
Synetech10-Sep-06 20:30
Synetech10-Sep-06 20:30 
GeneralRe: Sorry, but like an typical french Pin
Kochise10-Sep-06 21:14
Kochise10-Sep-06 21:14 
GeneralRe: Sorry, but like an typical french Pin
CPallini7-Feb-10 20:55
mveCPallini7-Feb-10 20:55 
GeneralRe: Sorry, but like an typical french Pin
MGutmann7-Feb-10 21:44
MGutmann7-Feb-10 21:44 
GeneralRe: Sorry, but like an typical french Pin
CPallini7-Feb-10 21:51
mveCPallini7-Feb-10 21:51 
GeneralRe: Sorry, but like an typical french Pin
MGutmann7-Feb-10 22:10
MGutmann7-Feb-10 22:10 
GeneralRe: Sorry, but like an typical french Pin
CPallini7-Feb-10 22:28
mveCPallini7-Feb-10 22:28 
GeneralRe: Sorry, but like an typical french Pin
Kochise3-Sep-10 0:20
Kochise3-Sep-10 0:20 
GeneralRe: Sorry, but like an typical french Pin
CPallini3-Sep-10 0:29
mveCPallini3-Sep-10 0:29 
GeneralRe: Sorry, but like an typical french Pin
Kochise10-Sep-10 3:39
Kochise10-Sep-10 3:39 
GeneralRe: Sorry, but like an typical french Pin
CPallini10-Sep-10 6:20
mveCPallini10-Sep-10 6:20 
QuestionBlending sorted, what about meta data? Pin
Fred W6-Apr-06 23:13
Fred W6-Apr-06 23:13 
AnswerRe: Blending sorted, what about meta data? Pin
Kochise6-Apr-06 23:19
Kochise6-Apr-06 23:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.