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


using System.Drawing;

// 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..
       Graphics graphics;
       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;
            tempGraphics.Dispose();
            tempImage.Save(Server.MapPath(GetImagePath(strNewImage, strDir)), System.Drawing.Imaging.ImageFormat.Png);
            tempImage.Dispose();
    }

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.

Tags

#C##.NET
If you read this far, then I hope you enjoyed this post and found it useful! Consider adding to my daily coffee funds to continue to provide better and more helpful articles in the future!
Maybe later

Add a comment

Send me your weekly newsletter filled with awesome ideas
Post comment