Click here to Skip to main content
Click here to Skip to main content

WaterMarker

By , 5 Apr 2006
 

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

About the Author

Kochise
Software Developer
France France
Member
KOCH David, 31 years old
Coder (embedded C/C++, ASM, Erlang)

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generaltext watermarkmemberxijun22 Apr '06 - 16:26 
I think that you may add a function about text watermark.
GeneralRe: text watermarkmemberKochise23 Apr '06 - 9:41 
I surely will, but I need to implement FreeType2 in order to provide good looking text... Will see in the next update Smile | :) Thanks for the feedback !
 
Kochise
 
In Code we trust !
QuestionRe: text watermarkmemberSynetech10 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 watermarkmemberKochise10 Sep '06 - 21:11 
Yeah, abuse of language to fool search engines Smile | :)
 
Kochise
 
In Code we trust !

GeneralSorry, but like an typical frenchmemberMessnerEW11 Apr '06 - 0:01 
Sorry to say that, but you do behave like an
typical french and think, the rest of the
world has to speak french.
But that's ok, sooner or later even your nation
will lern it.

GeneralRe: Sorry, but like an typical frenchmemberKochise11 Apr '06 - 8:57 
Why should all people speak english ? I speak 3 languages, how many you do ? I'll update the software soon, in english to wider its audience, don't worry Smile | :) I just coded this in 2 hours for a friend of mine who hardly speak english (like you, he dislike foreigners that tends to impose their point of view)...
 
I'm awaiting more constructive critisism and advices, then compile everything into the next update Smile | :)
 
Kochise
 
In Code we trust !
GeneralRe: Sorry, but like an typical frenchmemberMessnerEW11 Apr '06 - 20:04 
Hm, I do speak english, german (native), and an horrible kind of
dialekt. If I'm wrong please correct me, but i thought englisch
is the number one language.
But never mind, just forget it. I wont bother you more.

GeneralRe: Sorry, but like an typical frenchmemberKochise11 Apr '06 - 22:26 
Ach, das ist ein problem, warum Deutsh war nicht das 'number one' sprache ? Etwas schlecht ?
 
Yet, I noticed this isn't translated right now, have you had trouble understanding this part ?
 
And french isn't that far from english :
 
Source -> Source
Destination -> Destination
Format -> Format
Répertoire -> repertory (aka directory aka folder)
Transparence -> transparency
Type -> type
Dimension -> dimension
... -> ...
 
And due to the real-time behavior of my UI, people can understand quite easily the purpose of each control Smile | :)
 
Kochise
 
In Code we trust !
 
-- modified at 4:30 Wednesday 12th April, 2006
GeneralRe: Sorry, but like an typical frenchmemberMessnerEW11 Apr '06 - 23:01 
Nein, deutsch wäre kein Problem.
 
But I think a little bit more then others (perhaps ?) and
that's the reason why I prefer english ( even it's not perfect ).
 
BUT, like I said at my first posting "TYPICAL FRENCH".
 
Oh, by the way, I wont respond on further messages.

GeneralRe: Sorry, but like an typical frenchmemberKochise11 Apr '06 - 23:34 
"But I think a little bit more then others"
 
Yeah, sure, you're wiser Smile | :) Anyway, thanks for your feedback... At least you took some time to interact with the coder to share your experience with the software.
 
I note (doodling on a post it) : using foreigner language turns people angry. Don't force people to read at something they (pretend) cannot understand... Uniformity is the rule. Plain english for the next release ! No lazyness this time...
 
OK dude, it's on schedule, hope you'll like the next one Smile | :)
 
Kochise
 
In Code we trust !

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 5 Apr 2006
Article Copyright 2006 by Kochise
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid