8 Replies Latest reply: Feb 23, 2014 6:13 AM by lrosenth RSS

    Indexed png transparency using /Mask

    nanoBarry Community Member

      Hi,

       

      is it possible to use an indexed png's palette and accompanying transparency data to display a masked image? I've seen enough evidence in other opensource pdf libraries  to suggest that it's possible, but am having trouble getting it working myself.

       

      The indexed PNG's i've tested all contain an array of  palette data and an associated array of transparency values.

       

      I'm able to successfully display the png in a pdf, when only using it's palette and excluding the transprancy. The transparent parts of the image are displayed as black, as expected . The outuput is,

       

      17 0 obj

      <</Type /XObject

      /Subtype /Image

      /Width 16

      /Height 16

      /ColorSpace [/Indexed /DeviceRGB 15 18 0 R]

      /BitsPerComponent 4

      /Filter /FlateDecode

      /DecodeParms <</Predictor 15 /Colors 1 /BitsPerComponent 4 /Columns 16>>

      /Length 155>>

      stream

      --------------- BINARY IMAGE DATA ---------------

      endstream

      endobj

       

      18 0 obj

      << /Length 48>>

      stream

      --------------- PALETTE ARRAY VALUES AS BINARY ---------------

      endstream

      endobj

       

       

      But as soon as i try an add the transparency array, nothing gets displayed and i get an error when opening the pdf that says 'An error exists on this page'. The transparency values for the indexed image are as follows,

       

      [255, 255, 192, 192, 160, 160, 128, 128, 96, 96, 64, 64, 32, 32, 0, 0]

       

      I've followed the spec, 8.9.6.4 Colour Key Masking, although i'm not sure if there should be a difference between 'min' and 'max' or whether it's just the same value duplicated? From the logic i've seen in other pdf generation libraries, it appears to be the latter.

       

      This is the non working output i get, when attempting to use the above array of transparency values as a mask,


       

      17 0 obj

      <</Type /XObject

      /Subtype /Image

      /Width 16

      /Height 16

      /ColorSpace [/Indexed /DeviceRGB 15 18 0 R]

      /BitsPerComponent 4

      /Filter /FlateDecode

      /DecodeParms <</Predictor 15 /Colors 1 /BitsPerComponent 4 /Columns 16>>

      /Mask [255 255 255 255 192 192 192 192 160 160 160 160 128 128 128 128 96 96 96 96 64 64 64 64 32 32 32 32 0 0 0 0 ]

      /Length 155>>

      stream

      --------------- BINARY IMAGE DATA  ---------------

      endstream

      endobj

       

      18 0 obj

      << /Length 48>>

      stream

      --------------- PALETTE ARRAY VALUES AS BINARY ---------------

      endstream

      endobj


        • 1. Re: Indexed png transparency using /Mask
          Test Screen Name CommunityMVP

          I think you are making a step that the PDF reference doesn't say. The colour mask values are in reference to values in the image colour space. But the image colour space is Indexed; you seem to be treating it as if its underlying colour space was the actual colour space, if I read the repetition correctly. Your values will need to be in the range of image colorants.

          • 2. Re: Indexed png transparency using /Mask
            nanoBarry Community Member

            Thanks, but i'm not sure i understand. Do you have an example of what you mean?

             

            I've followed through the logic of 3 seperate pdf libraries and all just strip the palette values and transparency values from a PNG's PLTE chunk and it's tRNS chunk and then apply them to the output to generate the pdf.

             

            They all have the same logic to output the trns properties as a /Mask property on the image object

             

            var trns = '',

             

            for (var i=0; i < img['trns'].length; i++)

                 trns += (img['trns'][i] + ' ' + img['trns'][i] + ' ');

            out('/Mask [' + trns + ']');

             

            Which converts the input of,

             

            [255, 255, 192, 192, 160, 160, 128, 128, 96, 96, 64, 64, 32, 32, 0, 0]

             

            to the output of

             

            /Mask [255 255 255 255 192 192 192 192 160 160 160 160 128 128 128 128 96 96 96 96 64 64 64 64 32 32 32 32 0 0 0 0 ]

            • 3. Re: Indexed png transparency using /Mask
              Test Screen Name CommunityMVP

              Let's go back. I'm not intimate with PNG. You say the transparency values for this PNG image are [255, 255, 192, 192, 160, 160, 128, 128, 96, 96, 64, 64, 32, 32, 0, 0]  but what does that actually mean? How many values are there and how to read them?

              • 4. Re: Indexed png transparency using /Mask
                nanoBarry Community Member

                I appreciate your help, but if you don't understand PNG's, then you're probably not the best person to answer this question. It would take a while for me to fully explain the PNG spec to you.

                • 5. Re: Indexed png transparency using /Mask
                  Test Screen Name CommunityMVP

                  Your choice. But I don't need to understand PNG, only PDF. You have to convert PNG -> understood concept -> PDF. To start with I'd expect values in the range of 0 to 31, wouldn't you? That's what 32000-1 says for BitsPerComponent=4.

                  • 6. Re: Indexed png transparency using /Mask
                    lrosenth Adobe Employee

                    It's possible but it's not trivial, which is why most libraries just undo the palettization and use a full color image + mask.

                     

                    The reason for the complexity is due to the differences between the way PNG encodes the data vs. how PDF does it.  So you will need to do some fancy tricks to get the data converted.  And it's much easier (and faster) to just undo the palettes.

                    • 7. Re: Indexed png transparency using /Mask
                      nanoBarry Community Member

                      Great, thanks a lot. I'd started to make inroads with this yesterday and slowly came to the same conclusion you've helpfully now confirmed!

                       

                      I noticed yesterday that the majority of indexed PNG's i've come across usually only have an array of transparency values  consisting of a single 0 with the rest being 255. From looking at an existing  PDF generator, i realised that when that's the case, you can just pass a single value  (instead of the complete array) to add the /Mask to an image. With that value being the index of the position of the 0 within the PNG's transparency array. This works fine for the majority of indexed pngs that i've tested, as most only elect a single (pixel) colour within their palette to represent a fully transparent pixel and the rest are fully opaque.

                       

                      So if the PNG's tRN's values are as follows,

                       

                      [255, 255, 255, 255, 255, 255, 0]

                       

                      then the /Mask would be set as

                       

                      /Mask [6, 6]

                       

                      After getting this to work, i'd started to think about how this might work with multiple values with varying transparency values. But then realised that it would probably just be easier to unroll it and create an image and sMask.

                       

                      Out of interest, do you know where i might look to find an example or explanation of how to apply the non-trivial solution? Is there anything within the PDF reference?

                      • 8. Re: Indexed png transparency using /Mask
                        lrosenth Adobe Employee

                        Yes, that's a chroma-key mask (where you pick one color from the possible color set).  You could also do a regular stencil mask, but that's the hard one.  SMask would be simpler since you could leave the palette in place but then make a full set in there - a definitely option if you are OK with adding transparency of that type to the document.