jemiah
jemiah

Reputation: 63

How to fix strange IHDR properties with Python Wand?

I'm attempting to generate an RGBA PNG file that has a format compatible with a RIP software I'm using. The problem is that it doesn't like the transparency data generated by Wand. I have an example file that the RIP software DOES like. I used the Imagemagick "identify -verbose" command to check the properties of the known-good file. What I found was that even though many other properties match my file, the IHDR properties are very different. In the file that loads properly I see:

png:IHDR.bit-depth-orig: 8
png:IHDR.bit_depth: 8
png:IHDR.color-type-orig: 6
png:IHDR.color_type: 6 (RGBA)

This is the example file that loads properly (In Chrome the transparent background looks black)

When I check the properties of the file generated with Wand I see:

png:IHDR.bit-depth-orig: 4
png:IHDR.bit_depth: 4
png:IHDR.color-type-orig: 3
png:IHDR.color_type: 3 (Indexed)
png:PLTE.number_colors: 8

This is the example file that FAILS to load properly (In Chrome the transparent background looks black)

I'm using:

ImageMagick 7.0.8-12 Q16 x86_64 2018-10-23
Wand==0.4.4

The code to draw this file creates three colored boxes on a transparent background for a printer test pattern. Here's it is:

from wand.image import Image
from wand.color import Color
from wand.drawing import Drawing

depth   = 32
max_dpi = 300
width   = 600
height  = 600

big_square_color    = Color('blue') #Color('transparent')
med_square_color    = Color('red')
small_square_color  = Color('green')
background_color    = Color('transparent')

# with Image(width=width, height=height, resolution=max_dpi, depth=depth, background=background_color) as source_img:
with Image(width=width, height=height, resolution=max_dpi, background=background_color) as source_img:
    source_img.depth  = 8
    with Drawing() as draw:

        # Draw a big box in the middle
        draw.stroke_color = draw.fill_color = big_square_color
        draw.rectangle(left=(width/16), top=(height/16), right=width-(width/16), bottom=height-(height/16))

        # Draw a smaller box in the middle
        draw.stroke_color = draw.fill_color = med_square_color
        draw.rectangle(left=(width/8), top=(height/8), right=width-(width/8), bottom=height-(height/8))

        # Draw the smallest box in the middle
        draw.stroke_color = draw.fill_color = small_square_color
        draw.rectangle(left=(width/4), top=(height/4), right=width-(width/4), bottom=height-(height/4))

        draw(source_img)

    source_img.format   = 'png'
    source_img.units    = 'pixelspercentimeter'
    source_img.colorspace  = 'srgb'
    source_img.type     = 'truecolor'
    source_img.alpha_channel = True

    source_img.save(filename='output.png')

Looking through the documentation for Imagemagick and for Wand I don't see a way to force the IHDR values. Does anyone know a way to change properties of a Wand.Image object to get IHDR.color_type:6 and png:IHDR.bit_depth:8?

Upvotes: 1

Views: 194

Answers (1)

emcconville
emcconville

Reputation: 24439

Mark's comments are correct. The PNG encoder doesn't think there's enough image-data to justify RBGA color type, so it optimized the image with INDEXED color palette. Prefixing the PNG32: protocol to the outbound file name, or setting source_img.format = 'PNG32' should work.

Looking through the documentation for Imagemagick and for Wand I don't see a way to force the IHDR values.

Anthony's Usage docs covers this, but reads more in a "Oh by the way" comment. Wand's documentation recently started hinting at delegate protocols, but I agree, that could also use better detail / coverage on this topic. Neither document calls much attention to IHDR (image header), so that might not be the best key-term to search for.

Upvotes: 2

Related Questions