0

I have a set of images (PNG) with manipulation parameters e.g. scale/rotate/x/y for each image, I would like to place them onto a fixed size (but bigger enough) blank image with above manipulation parameters.

I think I can do it all manually with PIL but some of the tasks seems tricky e.g. 45 degree rotating will lose some of the area of the image and I probably have to put in in a temporary bigger size place holder first then do the rotating, finally put it in the final place holder. Do we have some good examples/library that can make it easier or more straightforward?

John
  • 2,107
  • 3
  • 22
  • 39
  • You can do it with cairo. See e.g. http://stackoverflow.com/questions/7145780/pycairo-how-to-resize-and-position-an-image . – Dov Grobgeld Mar 03 '14 at 07:29
  • sound like Cairo is a vector lib? even lower layer operation? probably better to have some example in PIL for rotating an image nicely – John Mar 03 '14 at 08:25
  • Rotating, scaling and translation an image by arbitrary coordinates is in a sense a vector operation already, so why not? What do you loose by using cairo? – Dov Grobgeld Mar 03 '14 at 09:20
  • will the built-in rotating in cairo work nicely? e.g. for the case I mentioned above? – John Mar 03 '14 at 10:32

1 Answers1

1

Here's a complete example of how to create a background image and paste multiple images into it with pycairo. It is partially based on pyCairo: How to resize and position an image?, but extended to support image rotation.

#!/usr/bin/python

# An example of how to create a background image and paste
# multiple images into it with pycairo.

import cairo
import math
import os

def pre_translate(ctx, tx, ty):
    """Translate a cairo context without taking into account its
    scale and rotation"""
    mat = ctx.get_matrix()
    ctx.set_matrix(cairo.Matrix(mat[0],mat[1],
                                mat[2],mat[3],
                                mat[4]+tx,mat[5]+ty))

def draw_image(ctx, image, centerX, centerY, height, width, angle=0):
    """Draw a scaled image on a given context."""
    image_surface = cairo.ImageSurface.create_from_png(image)

    # calculate proportional scaling
    img_height,img_width = (image_surface.get_height(),
                            image_surface.get_height())
    scale_xy = min(1.0*width/img_width,1.0*height / img_height)

    # scale, translate, and rotate the image around its center.
    ctx.save()
    ctx.rotate(angle)
    ctx.translate(-img_width/2*scale_xy,-img_height/2*scale_xy)

    ctx.scale(scale_xy, scale_xy)
    pre_translate(ctx, centerX, centerY)
    ctx.set_source_surface(image_surface)

    ctx.paint()
    ctx.restore()

width,height=512,512
surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, width, height)
cr = cairo.Context (surface)
pre_translate(cr, 0,0)

# Create the background
cr.rectangle(0,0,width,height)
cr.set_source_rgb(0,0,0.5)
cr.fill()

# Read an image
imagefile = 'tux.png'
if not os.path.exists(imagefile):
  import urllib
  urllib.urlretrieve('http://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png', imagefile)

for x in range(0,width,64):
    for y in range(0,height,64):
        angle = 1.0*(x+y)/(width+height-128)*2*math.pi
        draw_image(cr,
                   imagefile,
                   x+32,y+32,
                   64,64,
                   angle)
Community
  • 1
  • 1
Dov Grobgeld
  • 4,783
  • 1
  • 25
  • 36