I'm trying to create a PDF file containing a monochrome 1-bit image, but configure the image to be transparent where it contains white pixels (so that content under the image is visible). The image uses the DeviceGray
color space, and BitsPerComponent
is 1.
I'm using the Mask
entry with an array specifying the color range which should be masked. My copy of the PDF spec calls this "Colour Key Masking". Since the image is bitonal, this color range is just [1 1]
(white).
However, I simply can't get this to work. The content under the image never displays. I've tried tweaking the range values, changing the image filter, tweaking the surrounding graphics state -- all to no avail.
The only thing that has worked has been to change the image color space from DeviceGray
to DeviceRGB
and tweak the Mask
ranges accordingly, but that would increase the size of these images in the PDF file, which I cannot do.
What is the correct way to use color key masking on bitonal DeviceGray
images?
Here's the image that I think should work, but does not:
6 0 obj
<<
/Length 8800
/Type /XObject
/Subtype /Image
/Filter /ASCIIHexDecode
/BitsPerComponent 1
/Width 350
/Height 100
/ColorSpace /DeviceGray
/Mask [1 1]
>>
stream
FFFF<snip>FFFC
endstream
endobj
EDIT: Adding full sample PDF file for full context. The file contains an image with the text "XYZ", and a line that runs under the XYZ image, which is hidden by the image but should be visible under the text:
%PDF-1.4
%צה
1 0 obj
<<
/Type /Catalog
/Version /1.4
/Pages 2 0 R
>>
endobj
2 0 obj
<<
/Type /Pages
/Kids [3 0 R]
/Count 1
>>
endobj
3 0 obj
<<
/Type /Page
/MediaBox [0.0 0.0 612.0 792.0]
/Parent 2 0 R
/Contents 4 0 R
/Resources 5 0 R
>>
endobj
4 0 obj
<<
/Length 53
>>
stream
0 396 m
612 396 l
S
q
90 0 0 80 261 356 cm
/Im1 Do
Q
endstream
endobj
5 0 obj
<<
/XObject <<
/Im1 6 0 R
>>
>>
endobj
6 0 obj
<<
/Length 1920
/Type /XObject
/Subtype /Image
/Filter /ASCIIHexDecode
/BitsPerComponent 1
/Width 90
/Height 80
/ColorSpace /DeviceGray
/Mask [1 1]
>>
stream
FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FE0FFF8307FFF8380000FFC0FF07FF0783FFF0780000FFC0FF87FE0FC3FFF0F80000FFC0FF83FE0FC1FFE0F80000FFC0FFC1FC1FE0FFC1FFFFE0FFC0FFE0F83FF0FFC3FFFFC1FFC0FFF0F87FF07F83FFFF83FFC0FFF0707FF83F07FFFF07FFC0FFF820FFFC3F0FFFFF07FFC0FFFC21FFFC1E0FFFFE0FFFC0FFFC01FFFE1C1FFFFC1FFFC0FFFE03FFFF0C3FFFF83FFFC0FFFF07FFFF003FFFF07FFFC0FFFF07FFFF807FFFF07FFFC0FFFE03FFFFC0FFFFE0FFFFC0FFFC01FFFFC0FFFFC1FFFFC0FFFC21FFFFE1FFFF83FFFFC0FFF820FFFFE1FFFF83FFFFC0FFF0707FFFE1FFFF07FFFFC0FFF0F87FFFE1FFFE0FFFFFC0FFE0F83FFFE1FFFC1FFFFFC0FFC1FC1FFFE1FFFC1FFFFFC0FFC3FE1FFFE1FFF83FFFFFC0FF83FE0FFFE1FFF07FFFFFC0FF07FF07FFE1FFE0FFFFFFC0FE0FFF83FFE1FFE000007FC0FE1FFFC3FFE1FFE000007FC0FC1FFFC1FFE1FFE000007FC0F83FFFE0FFE1FFE000007FC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFFFFFC0
endstream
endobj
xref
0 7
0000000000 65535 f
0000000015 00000 n
0000000078 00000 n
0000000135 00000 n
0000000247 00000 n
0000000352 00000 n
0000000399 00000 n
trailer
<<
/Root 1 0 R
/ID [<DF10D2517650DA8AC34FF5D6B9B046EA> <DF10D2517650DA8AC34FF5D6B9B046EA>]
/Size 7
>>
startxref
2505
%%EOF
EDIT 2: Thanks to iPDFdev's confirmation that this should indeed work, I dug deeper into the reader side of things. It turns out that there is a bug in SumatraPDF, and there was also a bug in the older version of Acrobat Reader that I was using.
After updating Acrobat Reader, the simplified example is working, but a more complex example involving Forms is still not working -- it seems that this is perhaps an area of the PDF spec that is not widely used or as battle-tested as others, even in Acrobat Reader. I'll probably stay away from the DeviceGray
+ bitonal + Mask
combination for the time being, due to compatibility concerns, and use the less efficient SMask
option instead.
All examples (both simple and complex) are working correctly in the iOS, Chrome and Firefox viewers, so I just happened to choose the two worst reader options to test this.
Without seeing the entire file I cannot say why the mask is not applied.
But the file below shows that the /Mask is applied to /DeviceGray bitonal images:
4 0 obj
<<
/Type /Page
/Resources <</XObject <</XO0 6 0 R>>>>
/Contents [5 0 R ]
/MediaBox [0 0 612 792 ]
/Parent 3 0 R
>>
endobj
5 0 obj
<<
/Length 103
>>
stream
/DeviceRGB cs
0 1 0 sc
50 650 m 250 650 l 250 750 l 50 750 l h f
q 200 0 0 100 50 650 cm /XO0 Do Q
endstream
endobj
6 0 obj
<<
/Subtype /Image
/Width 16
/Height 8
/BitsPerComponent 1
/ColorSpace /DeviceGray
/Mask [1 1]
/Length 16
>>
stream
UUUUUUUUUUUUUUUU
endstream
endobj
This is the result (image drawn on top of green rectangle, U=01010101, white color (1) is transparent):