Generating perspective-skewed mock-up images for printed products with Python

For Moment Wall Art (and other printed product sites in future), we need to show the customer not just the main print design itself but also mock-up images demonstrating how it would look in various settings.

Applying a perspective skew to images like this can be handled by the Python Wand library, specifically with the perspective distortion function.

I have a Python script that iterates through a glob of all product files in parallel, and generates these perspective-skewed mock up images where necessary.

The key part of the script that applies the perspective-skew looks like this:

with Image(filename=src_path) as src:
    with Image(filename=template_path) as template:
        overlay = Image(width=template.width, height=template.height)
        overlay.virtual_pixel = "transparent"
        overlay.composite(src)

        source_points = (
            (0, 0),
            (src.width, 0),
            (0, src.height),
            (src.width, src.height),
        )
        order = chain.from_iterable(
            zip(source_points, dest_points_for_template(template_key))
        )
        distort_args = list(chain.from_iterable(order))

        overlay.distort("perspective", distort_args)

        template.composite(overlay)
        template.save(filename=output_path)

One thing that is slightly fiddly is the need for a third temporary “middle sheet” image that the source image is composited on to before being skewed. If the source image is skewed directly without this step, and is smaller in any dimension that the target template image, parts of it will exceed the canvas and be sheared off.

With this in place, it’s easy to manage a set of template images that will generate product mock-up photos for all products:

DestPoints = Tuple[Tuple[int, int], Tuple[int, int], Tuple[int, int], Tuple[int, int]]

TEMPLATE_POINTS = {  # type: Dict[str, DestPoints]
    "bricks": ((562, 401), (1487, 400), (561, 1647), (1487, 1648)),
    "desk-window": ((580, 136), (1213, 158), (596, 1054), (1217, 1036)),
    "living-room": ((803, 498), (1083, 569), (791, 972), (1077, 1013)),
    "plain-plants": ((788, 705), (1380, 700), (784, 1539), (1382, 1542)),
    "tiles": ((784, 452), (1487, 510), (737, 1484), (1413, 1677)),
    "wall-window": ((1146, 548), (1590, 514), (1142, 1297), (1583, 1324)),
    "wooden-floor-light-angle": ((988, 321), (1889, 297), (908, 1581), (1772, 1865)),
}

View post: Generating perspective-skewed mock-up images for printed products with Python