As a developer, I hate using 3rd party software to accomplish things that would take a few minutes or hours of work. For example, watermarking images. At my last job one of the websites that I happened to grace my eyes upon had such a library to watermark uploaded images. One day, it stopped working and I had to figure out why. Days later, it turned out that there had been an update to that library and it required some further configuration that didn't get updated and there we were.
That's my main problem with using 3rd party software to do things that I know how to do and would only take a bit of time to implement. On almost anything that I build, I can detect the location of an error within less than 60 seconds, because having built it I know all the ins and outs. Soon after that job I implemented my own watermarking application and lived happily ever after. Here it is for your viewing pleasure. I've trimmed a bit of the fat of the original code to keep things tidier and simpler. It takes a bit of practice to get used to the drawing libraries in .NET, but once you're comfortable you can pretty much build anything.
The watermark process is pretty simple. It essentially creates a bitmap object from the image you specify, then creates another layer on top of that one
// watermarks the image being passed in..
public void WatermarkImage(string strImagePath)
string watermarkText= "HELLO WORLD";
Image tempImage; // image object for specified file
Bitmap objBitmap; // used to build up graphics object..
int ImageHeight = 0; // height of tempImage..used to build up bitmap
int ImageWidth = 0; // width of tempImage..used to build bitmap
Font watermarkFont = new System.Drawing.Font("Arial", 12, System.Drawing.FontStyle.Regular);
SizeF labelSize = new SizeF();
// grab image from path passed in
tempImage = Image.FromFile(strImagePath); // create an image object from the specified file..
ImageHeight = tempImage.Height; // get the image height
ImageWidth = tempImage.Width; // get the image width
Ignoring the variable list, for the time being, we're loading an Image object with the image located at the path that is passed in.
// create new bitmap with the images dimensions..
objBitmap = new System.Drawing.Bitmap(tempImage.Width, tempImage.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
// create new graphics object from the bitmap object
graphics = Graphics.FromImage(objBitmap);
// draws Image to the Graphics object, at position x = 0, y = 0 at 100% original size..
// all future drawings will be on top of the original photograph
// sets antialiasing on essentially
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphics.DrawImage(tempImage, new System.Drawing.Rectangle(0, 0, tempImage.Width, tempImage.Height), 0, 0, tempImage.Width, tempImage.Height, System.Drawing.GraphicsUnit.Pixel);
Here we're loading the image into a Bitmap object and then using that object to draw the image on to the Graphics object. We set the Graphics objects SmoothingMode to HighQuality to get antialiased lines in our drawing. In the picture on the left, the left line has no SmoothingMode set.
// we're going to draw our watermark somewhere in the middle of the picture
int yPixelsFromBottom = (int)(tempImage.Height * .50);
float yPositionFromBottom = ((intImageHeight - yPixelsFromBottom) - (labelSize.Height / 2));
float xCenterOfImage = (tempImage.Width / 2);
StringFormat strFormat = new StringFormat();
strFormat.Alignment = System.Drawing.StringAlignment.Center;
// draw watermark label..we've set the opacity to 80% here with the first parameter
SolidBrush semiTransparentBrush2 = new SolidBrush(Color.FromArgb(80, 96, 96, 96));
graphics.DrawString(watermarkText, watermarkFont, semiTransparentBrush2, new PointF(xCenterOfImage + 2, yPositionFromBottom + 2), strFormat);
// now we save our new image from the Graphics object and dispose of all objects
string strNewImage = Guid.NewGuid().ToString() + Path.GetExtension(strImagePath);
image = objBitmap;
tempImage.Save(Server.MapPath(GetImagePath(strNewImage, strDir)), System.Drawing.Imaging.ImageFormat.Png);
This is much more satisfying than downloading a library, implementing it onto your site, and then hoping that at some point down the road it doesn't brick itself and become useless. You can tweak it in any way that you want such as drawing images instead of text as a watermark. The main takeaway in this example is loading the image onto a Graphics object and once you have that ready, drawing whatever else you want on top of that image and exporting it to a file.
Walter G. is a software engineer, startup co-founder, former CTO of several tech companies and currently teaches programming for a coding bootcamp. He has been blogging for the past 5 years and is an avid BMX rider, bio-hacker
and performance enthusiast.
Stay up to date with my weekly coding tips!