Adding a “watermark” to an image in ASP.NET

Currently I am working on a personal project in ASP.NET and one of the tasks is to store images in a MySQL database and later retrieve and show them to the users.

Just for demo purpose, the MySQL table structure is very simple:

db_structure

First step of my task was actually storing the images in the MySQL table and for that I used Entity Framework in order to simplify the data handling.

For adding a new image to the database I created one very simple ASP.NET page:

ASP.NET
  1. <asp:FileUpload ID="fileUploadControl" runat="server" />
  2. <asp:Button ID="UploadButton" runat="server" Text="Upload" OnClick="UploadButton_Click" /><br />
  3. <asp:Label ID="StatusLabel" runat="server" Text="" />

and the code behind for uploading the image and displaying the image details in case of success, or the error in case of any issue is:

C#
  1. protected void UploadButton_Click(object sender, EventArgs e)
  2. {
  3. if (fileUploadControl.HasFile)
  4. {
  5. try
  6. {
  7. ImagesDbEntities2 ent = new ImagesDbEntities2();
  8. images img = new images();
  9. img.name = fileUploadControl.FileName;
  10. img.data = fileUploadControl.FileBytes;
  11. img.type = fileUploadControl.PostedFile.ContentType;
  12. ent.AddToimages(img);
  13. ent.SaveChanges();
  14. StatusLabel.ForeColor = Color.Black;
  15. StringBuilder sb = new StringBuilder();
  16. sb.Append("File Name: " + fileUploadControl.FileName + "<br />");
  17. sb.Append("File Size: " + fileUploadControl.PostedFile.ContentLength + " bytes <br />");
  18. sb.Append("File Type: " + fileUploadControl.PostedFile.ContentType + "");
  19. StatusLabel.Text = sb.ToString();
  20. }
  21. catch (Exception ex)
  22. {
  23. StatusLabel.ForeColor = Color.Red;
  24. StatusLabel.Text = "EXCEPTION: " + ex;
  25. }
  26. }
  27. else
  28. {
  29. StatusLabel.ForeColor = Color.Red;
  30. StatusLabel.Text = "Please select a file to upload!";
  31. }
  32. }

The simple code above allows us to store images in the MySQL table, so next task is to retrieve an image and display it on a web page. For this I created a simple ASP.NET webpage which based on the image ID I pass in the query string it returns the image with that ID from the database. There is only code-behind written for this task and I have 2 implementations:

  1. writing some simple text on top of the image and center it
  2. using a custom image with transparent background and center it on top of the image

Most of the implementation for both ways of adding the watermark to the image is the same and consists in retrieving the table entry based on the ID we pass in the URL query string, creating a MemoryStream object based on the bytes stored on the data field and then create an Image object from the MemoryStream created previously. Also in order to write a text on top of the image or display the watermark image over the initial image we need to create a Graphics object and call the DrawString or DrawImage methods.

So, here is the code to display a text over the image retrieved from the database:

C#
  1. public partial class GetImage : System.Web.UI.Page
  2. {
  3. MemoryStream ms = null;
  4.  
  5. protected void Page_Load(object sender, EventArgs e)
  6. {
  7. if (!IsPostBack)
  8. {
  9. string id = Request.QueryString["id"];
  10. if (!string.IsNullOrEmpty(id))
  11. {
  12. ImagesDbEntities2 ent = new ImagesDbEntities2();
  13. long imgID = Convert.ToInt64(id);
  14. var image = (from img in ent.images where img.id == imgID select img).FirstOrDefault();
  15. if (image != null)
  16. {
  17. MemoryStream ms = new MemoryStream(image.data);
  18. System.Drawing.Image memImage = System.Drawing.Image.FromStream(ms);
  19. Graphics g = Graphics.FromImage(memImage);
  20. Font f = new Font("Arial", 12, FontStyle.Bold);
  21. SolidBrush brush = new SolidBrush(Color.Red);
  22. SizeF stringDimens = g.MeasureString("AndreiC - 2010", f, 300);
  23. if (stringDimens.Width < memImage.Width && stringDimens.Height < memImage.Height)
  24. {
  25. g.DrawString("AndreiC - 2010", f, brush,
  26. (memImage.Width - stringDimens.Width) / 2,
  27. (memImage.Height - stringDimens.Height) / 2);
  28. }
  29.  
  30. Response.ContentType = "image/Jpeg";
  31. memImage.Save(Response.OutputStream, ImageFormat.Jpeg);
  32.  
  33. // Clean-up
  34. ms.Dispose();
  35. memImage.Dispose();
  36. g.Dispose();
  37. }
  38. }
  39. }
  40. }
  41. }

If we want to display the image with ID=1 from the database, all we have to do is add the following HTML code in the page:

HTML
  1. <img src="GetImage.aspx?id=1" />

The result is:

text_test

In case you want to add an image as watermark over your database stored image, you can use the following code:

C#
  1. public partial class GetImage : System.Web.UI.Page
  2. {
  3. MemoryStream ms = null;
  4.  
  5. protected void Page_Load(object sender, EventArgs e)
  6. {
  7. if (!IsPostBack)
  8. {
  9. string id = Request.QueryString["id"];
  10. if (!string.IsNullOrEmpty(id))
  11. {
  12. ImagesDbEntities2 ent = new ImagesDbEntities2();
  13. long imgID = Convert.ToInt64(id);
  14. var image = (from img in ent.images where img.id == imgID select img).FirstOrDefault();
  15. if (image != null)
  16. {
  17. System.Drawing.Image watermark = System.Drawing.Image.FromFile(
  18. Server.MapPath("Images/andreic_watermark.png"));
  19. MemoryStream ms = new MemoryStream(image.data);
  20. System.Drawing.Image memImage = System.Drawing.Image.FromStream(ms);
  21. Graphics g = Graphics.FromImage(memImage);
  22.  
  23. // draw watermark only if image is larger than watermark image
  24. if (watermark.Height < memImage.Height && watermark.Width < memImage.Width)
  25. {
  26. g.DrawImage(watermark,
  27. (memImage.Width - watermark.Width) / 2,
  28. (memImage.Height - watermark.Height) / 2);
  29. }
  30. Response.ContentType = "image/Jpeg";
  31. memImage.Save(Response.OutputStream, ImageFormat.Jpeg);
  32. // Clean-up
  33. ms.Dispose();
  34. watermark.Dispose();
  35. memImage.Dispose();
  36. g.Dispose();
  37. }
  38. }
  39. }
  40. }
  41. }

For this implementation I had to create one additional PNG image with transparent background and I placed it in the project inside a folder named Images.

The HTML code to show the image stays the same and the result is:

img_watermark_test

Hope this helps!