1

I'd like to create a python script that would receive some text and photos, arrange and compose them following some rules, and output a final image. To do so, I would need a python library that could:

  • Read, scale and move pictures to create composite images.
  • Insert text and maybe some simple glyphs (circles, arrows)
  • Apply masks to images.

I've started using pycairo to that end, and while it is certainly very capable, it's rather slow and most certainly not the right tool for the job; it's vector graphics library, after all. There's Pillow as well, but I reckon it's too low-level.

Is there a python library better-suited to that task?

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
impresso
  • 79
  • 8
  • 1
    Correct me if I am wrong but can't you do these with OpenCV or are you looking for something else? – Batselot Apr 25 '22 at 20:03
  • I'm not familiar with it, I'll have a look! But it strikes me as a huge library, whereas what I'm looking for is a rather modest set of features. Ideally I'd find a small library such as `moviepy`, but for images. – impresso Apr 25 '22 at 20:08
  • 1
    Opencv is definitely the thing you are looking for. Hold up I will post a detailed answer about it. – Batselot Apr 25 '22 at 20:31
  • 1
    The Pillow port of the PIL can do all of those things — you may have to write some "low-level" code that uses it. – martineau Apr 25 '22 at 20:32
  • 2
    **OpenCV** is going to fall short if you want anything remotely interesting about your text, e.g. fonts or justification and if you want glyphs or annotations, IMHO. PIL will do better with text, but still not great with glyphs and layouts. – Mark Setchell Apr 25 '22 at 22:29

1 Answers1

3

Opencv is the library that is used mostly in imaging solutions. I will post some templates for the people who might be looking for these functions.

1)Read, scale and move pictures to create composite images.

import cv2
cv2.imread("Image path")
cv2.resize(original image,size)

cv2. is the way you can read an image in OpenCV. It is given to you as an array and with the resize function that should settle it out. For creating composite images, you can also do it with openCV as well here is a template I have gotten from here.

import numpy as np
import cv2

A = cv2.imread(r"C:\path\to\a.png", 0)
B = cv2.imread(r"C:\path\to\b.png", 0)

#C = cv2.merge((B,A,B))
C = np.dstack((B,A,B))
cv2.imshow("imfuse",C)
cv2.waitKey(0)
  1. Insert text and maybe some simple glyphs (circles, arrows)

cv2.putText()

can definitely solve your issue. It takes the image and the text as an argument. For inserting glyphs there are some other functions for that. One of those which is:
cv2.arrowedLine()

  1. Apply masks to images.

You can also apply masks to images. This is not a one liner here so I will leave a good link that I was relying on here.

For clarification as @martineau said you can do these with pillow but it might need some extra work on your part. And for the part that where you might need a smaller library you might consider using OpenCVlite but I haven't had any experience with it yet.

Batselot
  • 194
  • 10
  • 1
    This answer addresses all of the points I raised so I'm marking it as accepted, but I'll mull over @Mark Setchell's caveat, as text formatting is relevant to my project – impresso Apr 26 '22 at 02:23