How to make an image a qualified mask candidate in itext?

Category: 
Tags: image maskimagestransparencyiText 5

I want to mask an image using another image, for example A.jpg should be masked with image B.jpg. But when I tried to make the image B a mask, I got the following DocumentException:

This image cannot be an image mask

Is there any other way to mask an image using another image in iText? I know how to clip an image but the mask I need can be quite complex, not only rectangles or circles that can be drawn with ContentByte.

Posted on StackOverflow on Mar 17, 2015 by why1905

The reason why your code doesn't work is simple: image masks must be monochrome or grayscale; your JPG is a colored image.

Please take a look at the MakeJpgMask example. In this example, I took two normal JPG files and I used one as mask for the other, resulting in a rather spooky PDF: jpg_mask.pdf

Screen shot
Screen shot

To achieve this, I needed to change one colored JPEG into a black and white image:

public void createPdf(String dest) throws IOException, DocumentException {
    Document document = new Document(PageSize.A4.rotate());
    PdfWriter writer = 
        PdfWriter.getInstance(document, new FileOutputStream(dest));
    document.open();
    Image image = Image.getInstance(IMAGE);
    Image mask = makeBlackAndWhitePng(MASK);
    mask.makeMask();
    image.setImageMask(mask);
    image.scaleAbsolute(PageSize.A4.rotate());
    image.setAbsolutePosition(0, 0);
    document.add(image);
    document.close();
}
 
public static Image makeBlackAndWhitePng(String image)
    throws IOException, DocumentException {
    BufferedImage bi = ImageIO.read(new File(image));
    BufferedImage newBi = new BufferedImage(
        bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_USHORT_GRAY);
    newBi.getGraphics().drawImage(bi, 0, 0, null);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(newBi, "png", baos);
    return Image.getInstance(baos.toByteArray());
}

As you can see, we have converted berlin2013.jpg into a black and white image and we have used this as a mask for the colored javaone2013.jpg image.