This started as looking for a easy way to watermark some photos
that I was going to expose to the whole world. The first thing that
came into my mind was that I could use a specialized photo editing
software (like
Photoshop for
example) to apply the watermarks. This had the drawback that you
actually need to have such a program and that it is a highly
repetitive task which I wouldn’t want to do it over and over again
for hundreds of pictures. (to be fair it’s probably possible to
automate such a task, given that the photo editing software
supports it, and again probably the software that supports it is
not free).
What I wanted was a small command line utility that would take as
input the image and produce as output the watermarked image. Really
simple, right?
Well, believe it or not other people thought about it and there are
some utilities like that out there. The problem is that people who
wrote them actually expect you to buy them at prices over what they
are really worth.
So what I did was remember a few basic things about the .NET
Framework (which I knew better in a previous life) and try to put
together a small utility on my own. It’s written in C# and you’ll
need, at minimum, the .NET SDK to be able to compile it, but I
would recommend Visual C# (even if it’s the
freeExpress Edition).
.NET has decent support when it comes to working with images.
1) I’ll do this as a console application. So I’ll start from a
blank class that has the entry point defined as
static void Main(string[] args)
2) We need to pass the file we are trying to watermark as
parameter. We’ll not overwrite the file, we’ll create a new one
that has a similar name but with w_ in front. So we add the
following code:
if (args.Length == 1)
{
string file = args[0];
string filemod = “w_” + file;
file is the original filename passed as a parameter. filemod is the
new filename which we built.
3)The next thing we want to do is open the image file and
obtain a graphics object from it so we can draw on it. We’ll add
the following lines to the if block previously started:
try
{
Image imageFile = Image.FromFile(file);
Graphics grp = Graphics.FromImage(imageFile);
}
catch (Exception e)
{
Console.WriteLine(“Something went wrong!”);
Console.WriteLine(e.Message+Environment.NewLine+e.StackTrace);
}
Note the minimal care for situations in which things go wrong (for
example file is missing or we don’t have permissions to access it).
This is done for the sake of keeping it simple. In case something
goes wrong we’ll just let the one who uses the utility know.
Also please note that for this to work you also need a reference to
System.Drawing assembly in your project.
4)Next step is to write on the image itself. We will need a
font and a color. It would also be nice if the color was somewhat
transparent. Let’s do it:
Image imageFile = Image.FromFile(file);
Graphics grp = Graphics.FromImage(imageFile);
int alpha = 60;
Color customColorSh = Color.FromArgb(alpha, Color.White);
Font fontUsed = new Font(“Verdana”, 15, FontStyle.Bold);
grp.DrawString(“Copyrighted image”, fontUsed, new SolidBrush(customColorSh), new PointF(10, 10));
Alpha is the transparency. We set it to 60%. The color is white.
And we’ll draw the string at coordinates (10.10) - last parameter
for DrawString.
5) At this moment the image is watermarked. The final step we
need to do is save it. We’ll be using Jpeg encoder, if we can find
one:
ImageCodecInfo jpegEncoderInfo = null;
ImageCodecInfo[] encoderInfoArray = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo imageCodecInfo in encoderInfoArray)
{
if (0 == String.Compare(“image/jpeg”, imageCodecInfo.MimeType, true))
{
jpegEncoderInfo = imageCodecInfo;
}
}
// If a JPEG encoder was found, use it to save a Bitmap to a JPEG file,
// explicitly specifying a “quality” parameter of 100 (the maximum).
if (null != jpegEncoderInfo)
{
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
imageFile.Save(filemod, jpegEncoderInfo, encoderParameters);
}
That’s about it.
We have a basic command like watermark utility.
Here is the full source code:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace Wmark
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 1)
{
string file = args[0];
string filemod = "w_" + file;
try
{
Image imageFile = Image.FromFile(file);
Graphics grp = Graphics.FromImage(imageFile);
int alpha = 60;
Color customColorSh = Color.FromArgb(alpha, Color.White);
Font fontUsed = new Font("Verdana", 15, FontStyle.Bold);
grp.DrawString("Copyrighted image", fontUsed, new SolidBrush(customColorSh), new PointF(10, 10));
ImageCodecInfo jpegEncoderInfo = null;
ImageCodecInfo[] encoderInfoArray = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo imageCodecInfo in encoderInfoArray)
{
if (0 == String.Compare("image/jpeg", imageCodecInfo.MimeType, true))
{
jpegEncoderInfo = imageCodecInfo;
}
}
// If a JPEG encoder was found, use it to save a Bitmap to a JPEG file,
// explicitly specifying a "quality" parameter of 100 (the maximum).
if (null != jpegEncoderInfo)
{
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
imageFile.Save(filemod, jpegEncoderInfo, encoderParameters);
}
}
catch (Exception e)
{
Console.WriteLine("Something went wrong!");
Console.WriteLine(e.Message+Environment.NewLine+e.StackTrace);
}
}
}
}
}
I’m not in any way responsible for pictures you might destroy misusing this or for the malfunctioning in any way of the utility)