📜 ⬆️ ⬇️

Add a watermark to the image

Hi, Habrahabr!
Yesterday, after reading the article by SergeyVoyteshonok on drawing the logo of a site or company (in other words, a “watermark”) on user-uploaded images, I was surprised by some heaviness of the solution proposed by the author.
Then I promised to experiment a bit and offer a more rational option.


In my version, the draw method looks like this:

public void DrawWatermark(Image original, Bitmap watermark,
WatermarkPosition position, Color transparentColor, float opacity)
{
if (original == null )
throw new ArgumentNullException( "original" );
if (watermark == null )
throw new ArgumentNullException( "watermark" );
if (opacity < 0 || opacity > 1)
throw new ArgumentOutOfRangeException( "Watermark opacity value is out of range" );

Rectangle dest = new Rectangle(
GetDestination(original.Size, watermark.Size, position), watermark.Size);

using ( Graphics g = Graphics .FromImage(original))
{
ImageAttributes attr = new ImageAttributes();
ColorMatrix matrix = new ColorMatrix( new float [][] {
new float [] { opacity, 0f, 0f, 0f, 0f },
new float [] { 0f, opacity, 0f, 0f, 0f },
new float [] { 0f, 0f, opacity, 0f, 0f },
new float [] { 0f, 0f, 0f, opacity, 0f },
new float [] { 0f, 0f, 0f, 0f, opacity } });
attr.SetColorMatrix(matrix);
watermark.MakeTransparent(transparentColor);

g.DrawImage(watermark, dest, 0, 0, watermark.Width, watermark.Height,
GraphicsUnit.Pixel, attr, null , IntPtr .Zero);
g.Save();
}
}


* This source code was highlighted with Source Code Highlighter .

Additionally, we also use two things:
public enum WatermarkPosition
{
TopLeft = 0,
TopRight,
BottomLeft,
BottomRight,
Middle
}


* This source code was highlighted with Source Code Highlighter .

to specify the anchor point, and the method that returns us a specific watermark location depending on the image size and anchor point:
private static Point GetDestination(Size originalSize, Size watermarkSize, WatermarkPosition position)
{
Point destination = new Point(0, 0);
switch (position)
{
case WatermarkPosition.TopRight:
destination.X = originalSize.Width - watermarkSize.Width;
break ;
case WatermarkPosition.BottomLeft:
destination.Y = originalSize.Height - watermarkSize.Height;
break ;
case WatermarkPosition.BottomRight:
destination.X = originalSize.Width - watermarkSize.Width;
destination.Y = originalSize.Height - watermarkSize.Height;
break ;
case WatermarkPosition.Middle:
destination.X = (originalSize.Width - watermarkSize.Width) / 2;
destination.Y = (originalSize.Height - watermarkSize.Height) / 2;
break ;
}
return destination;
}

* This source code was highlighted with Source Code Highlighter .

In my opinion, everything is quite transparent. Actually drawing the logo took only 15 lines, taking into account all the formatting bells and whistles, and without them - even less! This result allowed to achieve the use of the capabilities of the .NET-class ColorMatrix for solving the problem.
In general, the ColorMatrix class has very wide possibilities for manipulating image settings. With it you can not only set the transparency, but also change the contrast, saturation of the picture, make it negative and much more.
')
In conclusion, two things should be noted. The first - the logo used as a watermark, it is better to save in PNG. GIF format for simple logos is also valid. In this case, we can not set transparentColor (more precisely, remove the line watermark.MakeTransparent(transparentColor); ) and expand the watermark type to Image.

The second, somewhat more important - my method performs the drawing directly on the image transferred to it, without creating a new instance. Therefore, if you need to save the original, you will need to slightly alter the method for drawing so that it returns the modified image without affecting the original one.

UPD: If you downloaded the original image from a file and want to save it with the same name, you will also need to create a copy and save it outside the using block.

UPD2: At the request of Sergeyev added a demonstration of the result (on the left - the original image, on the right - it’s with the well-known logo. Not Photoshop! :)


Well, that's all!

PS: So, absolutely imperceptibly, my first topic appeared on Habré :)

Source: https://habr.com/ru/post/41546/


All Articles