Home > Software > Watermark with JMagick

Watermark with JMagick


I know you can do watermarking in thousands of ways, but this is if you want to embed it in your Java application. I know that you can also do this with Java2D, but it’s so much easier with ImageMagick. Moreover you have JMagick distributions for most of the major OSes.
First of all, if you haven’t heard about JMagick, this is the Java/JNI implementation for ImageMagick.
Unfortunately the JMagick documentation is very few and it includes only a few examples.
This next example will guide step by step in adding a watermark to an image. The idea is simple: first you create a watermark image from a text and then combine this image with your initial image.
So, let’s create the watermark image. If you want to watermark more than one image, this will be a one time only step.

    // create the watermark image info structure
    ImageInfo markImageInfo = new ImageInfo();
    // set a size for the image high enough to accommodate the text 
    markImageInfo.setSize("1024x1024");
    // create the image
    markImage = new MagickImage();
    markImage.allocateImage(markImageInfo);
    // make the image transparent
    markImage.setMatte(true);
    // set the background image to black
    // actually the color doesn't matter, only the alpha value - 65535
    markImage.setBackgroundColor(new PixelPacket(0, 0, 0, 65535));
    // make the initial black background color transparent
    markImage.transparentImage(new PixelPacket(0, 0, 0, 0), 65535);

Now what we have is an image with a black transparent background. Next we have to paint the text on it. For this we will create the drawing and put it into the image.

    // create the drawing info structure
    ImageInfo drawInfo = new ImageInfo();
    // create the drawing structure
    DrawInfo draw = new DrawInfo(drawInfo);
    draw.setOpacity(0);
    draw.setGeometry("+0+0");
    draw.setGravity(GravityType.CenterGravity);    
    // set the watermark color to gray
    draw.setFill(new PixelPacket(0xaf00, 0xaf00, 0xaf00, 0));
    // set the font size
    draw.setPointsize(48);
    // set the font name or the path to the font file
    draw.setFont("Arial");
    // set the watermark text
    draw.setText("Adrian's blog");
    // make the text smoother
    draw.setTextAntialias(true);

Now we have the text and we have to put it into the watermark image:

    // draw the text on the image
    markImage.annotateImage(draw);
    // remove the transparent borders of the image so that only the text will remain
    markImage = markImage.trimImage();

The initial setup is finished. Now we have to load every image that we want to watermark it, combine it with the watermark image and save it.

    // load the image from the specified filename
    ImageInfo imageInfo = new ImageInfo(filename);
    MagickImage image = new MagickImage(imageInfo);
    // watermark the image
    image.compositeImage(CompositeOperator.HardLightCompositeOp, markImage, 10, 10);
    // save the image
    image.setFileName(watermarkedFilename);
    image.writeImage(imageInfo);

The watermark is put in the upper left corner, 10 pixels away from both borders. This is actually what the third and fourth parameters of the compositeImage method represent.
Instead of CompositeOperator.HardLightCompositeOp you may also use CompositeOperator.SoftLightCompositeOp or CompositeOperator.OverlayCompositeOp.
If you probably watermark the image you may also want to resize it

    image = image.scaleImage(newWidth, newHeight);

or remove the EXIF and IPTC info from it

    image.profileImage("*", null);

So, in just a few easy steps you were able to watermark an image (or more) with your text. The nice part is that using JMagick you can do a lot of other stuff with the same ease.
This solution can be easily embedded into GUI or web applications.

Later edit: I also tried the DissolveOp and the results are very good.

Categories: Software Tags: ,
  1. Simon
    July 14, 2009 at 4:36 am

    I hate jmagic..it makes my jvm runtime to shutdown…i also heared some other people reporting this JNI problem. I think it is better to use Process builder and directly use ImageMagic via its command line.

  1. November 14, 2008 at 11:50 pm

Leave a reply to Simon Cancel reply