Polaris - Non-destructive image watermarking in .NET
I did it. I have version 0.1 of my watermarking tool which I have named Polaris. When I feel it's ready for more people to test it, I'll put it up on my blog in case anyone will want to download it and give me feedback.
After having tryed a solution MarkMyImage from CodeProject, and finding it visibily (at least to me) reduces the quality of my images, I felt there was a problem with the way the code handled applying the watermarking. I thought I could do better, and since there were a couple of other things that bothered me (or that I'd like to have) I decided to do it. What I'm starting with is:
- Loadable Watermarking profiles with watermark drag&drop placement
- Automatic invert of watermark image if image is too bright or too dark to allow it to be visible
- Asynchronous processing (non-blocking UI)
However, the first issue I've encountered is that as much as I hoped it was the way the code handled the watermarking in MarkMyImage, it was actually .NET to blame. It appears that the call to Image's Save() method assumes a higher compression that expected. In particular, I believe it chooses 75% quality preservation. After doing some research and reading up on articles, I found this one.
The solution is to include the ImageCodecInfo object and EncoderParameters where the quality setting is set to 100. The code to do it is simple:
ImageCodecInfo myImageCodecInfo;
System.Drawing.Imaging.Encoder myEncoder;
EncoderParameter myEncoderParameter;
EncoderParameters myEncoderParameters;myImageCodecInfo = GetEncoderInfo("image/jpeg");
// Create an Encoder object based on the GUID
// for the Quality parameter category.
myEncoder = System.Drawing.Imaging.Encoder.Quality;
myEncoderParameters = new EncoderParameters(1);// Save the bitmap as a JPEG file with quality level 100.
myEncoderParameter = new EncoderParameter(myEncoder, 100L);
myEncoderParameters.Param[0] = myEncoderParameter;
//save new image to file system.
After this, all I had to do was call Save(path, myImageCodecInfo, myEncoderParameters);.
After I generated the images, I did a comparison of the original, Polaris image and the previous solution. This is the result:
I may be a bit to precise on this quality thing, but I saw the difference. And it bothered me. Can you see it? Now, the quality diference is minute (there will always be a difference due to the very nature of JPG).
Anyway, now I'll post some pictures =). Just as soon as I finish getting the solo guitar right from Jefferson's Starship - Nothing's gonna stop us now.
We can build this thing together. Stand in stone forever. Cause nothing's gonna stop us now!