Generate tiff with tifffile in python and set higher DPI than 1 to 300 and set eciRGB v2

Question:

I had to write a python script to generate tiff file but unfortunately I didn’t pass all requirements which need to be.

  1. DPI of the file need to be 300DPI
  2. and color model eciRGB v2

information from tiff file

here is the script:

from psdtags import *
from tifffile import imwrite
from imagecodecs import imread
import numpy as np
from PIL import Image


# backgroundImage = Image.open('GPD_TEST_Background.png')
productImage = Image.open('GPD_TEST_Product.png')
reflectionImage = Image.open('GPD_TEST_Reflection.png')
shadowImage = Image.open('GPD_TEST_Shadow.png')

w, h = productImage.size

# create background with defined color
backgroundImage = Image.new(mode="RGBA", size=(w,h), color=(255, 255, 255,255))

background = np.array(backgroundImage)
product = np.array(productImage)
reflection = np.array(reflectionImage)
shadow = np.array(shadowImage)

#thumbnail
thumbnail = Image.alpha_composite(backgroundImage, reflectionImage)
thumbnail = Image.alpha_composite(thumbnail, shadowImage)
thumbnail = Image.alpha_composite(thumbnail, productImage)
thumbnail = np.array(thumbnail)

image_source_data = TiffImageSourceData(
    name='Layered TIFF Test',
    psdformat=PsdFormat.LE32BIT,
    layers=PsdLayers(
        key=PsdKey.LAYER,
        has_transparency=False,
        layers=[
            PsdLayer(
                name='Background',
                rectangle=PsdRectangle(0, 0, *background.shape[:2]),
                channels=[
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL0,
                        compression=PsdCompressionType.RLE,
                        data=background[..., 0],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL1,
                        compression=PsdCompressionType.RLE,
                        data=background[..., 1],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL2,
                        compression=PsdCompressionType.RLE,
                        data=background[..., 2],
                    ),
                ],
                mask=PsdLayerMask(),
                opacity=255,
                blendmode=PsdBlendMode.NORMAL,
                blending_ranges=(),
                clipping=PsdClippingType.BASE,
                flags=PsdLayerFlag.PHOTOSHOP5
                | PsdLayerFlag.TRANSPARENCY_PROTECTED,
                info=[
                    PsdString(PsdKey.UNICODE_LAYER_NAME, 'Background'),
                ],
            ),
            PsdLayer(
                name='Reflection',
                rectangle=PsdRectangle(0, 0, *reflection.shape[:2]),
                channels=[
                    PsdChannel(
                        channelid=PsdChannelId.TRANSPARENCY_MASK,
                        compression=PsdCompressionType.RLE,
                        data=reflection[..., 3],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL0,
                        compression=PsdCompressionType.RLE,
                        data=reflection[..., 0],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL1,
                        compression=PsdCompressionType.RLE,
                        data=reflection[..., 1],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL2,
                        compression=PsdCompressionType.RLE,
                        data=reflection[..., 2],
                    ),
                ],
                mask=PsdLayerMask(),
                opacity=255,
                blendmode=PsdBlendMode.NORMAL,
                blending_ranges=(),
                clipping=PsdClippingType.BASE,
                flags=PsdLayerFlag.PHOTOSHOP5,
                info=[
                    PsdString(PsdKey.UNICODE_LAYER_NAME, 'Reflection'),
                ],
            ),
            PsdLayer(
                name='Shadow',
                rectangle=PsdRectangle(0, 0, *shadow.shape[:2]),
                channels=[
                    PsdChannel(
                        channelid=PsdChannelId.TRANSPARENCY_MASK,
                        compression=PsdCompressionType.RLE,
                        data=shadow[..., 3],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL0,
                        compression=PsdCompressionType.RLE,
                        data=shadow[..., 0],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL1,
                        compression=PsdCompressionType.RLE,
                        data=shadow[..., 1],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL2,
                        compression=PsdCompressionType.RLE,
                        data=shadow[..., 2],
                    ),
                ],
                mask=PsdLayerMask(),
                opacity=255,
                blendmode=PsdBlendMode.NORMAL,
                blending_ranges=(),
                clipping=PsdClippingType.BASE,
                flags=PsdLayerFlag.PHOTOSHOP5,
                info=[
                    PsdString(PsdKey.UNICODE_LAYER_NAME, 'Shadow'),
                ],
            ),
            PsdLayer(
                name='Product',
                rectangle=PsdRectangle(0, 0, *product.shape[:2]),
                channels=[
                    PsdChannel(
                        channelid=PsdChannelId.TRANSPARENCY_MASK,
                        compression=PsdCompressionType.RLE,
                        data=product[..., 3],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL0,
                        compression=PsdCompressionType.RLE,
                        data=product[..., 0],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL1,
                        compression=PsdCompressionType.RLE,
                        data=product[..., 1],
                    ),
                    PsdChannel(
                        channelid=PsdChannelId.CHANNEL2,
                        compression=PsdCompressionType.RLE,
                        data=product[..., 2],
                    ),
                ],
                mask=PsdLayerMask(),
                opacity=255,
                blendmode=PsdBlendMode.NORMAL,
                blending_ranges=(),
                clipping=PsdClippingType.BASE,
                flags=PsdLayerFlag.PHOTOSHOP5,
                info=[
                    PsdString(PsdKey.UNICODE_LAYER_NAME, 'Product'),
                ],
            ),
        ],
    ),
    usermask=PsdUserMask(
        colorspace=PsdColorSpaceType.RGB,
        components=(65535, 0, 0, 0),
        opacity=50,
    ),
    info=[
        PsdEmpty(PsdKey.PATTERNS),
        PsdFilterMask(
            colorspace=PsdColorSpaceType.RGB,
            components=(65535, 0, 0, 0),
            opacity=50,
        ),
    ],
)


imwrite(
    'LayeredTiffTest.tif',
    thumbnail,
    photometric='rgb',
    metadata=None,
    extratags=[image_source_data.tifftag()],
)

and to be honest I don’t know if I should try to find the way to put that information in imwrite or when the thumbnail is creating. I tried to changed photometric to eciRGB v2 but without any success.

Asked By: konradns

||

Answers:

Try to specify the resolution and an ICC color profile, e.g.,:

with open('eciRGBv2.icc', 'rb') as fh:
    icc = fh.read()

imwrite(
    'LayeredTiffTest.tif',
    thumbnail,
    photometric='rgb',
    resolution=((3000000, 10000), (3000000, 10000)),
    resolutionunit='INCH',
    metadata=None,
    extratags=[image_source_data.tifftag(), (34675, 7, None, icc, True)],
)
Answered By: cgohlke
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.