Recently, I had to arrange 60 images in ten arrays of 2x3 (2 columns, three rows). Luckily, I found a code in Python that can do the work for me. The code was written for Evan Rosica, and it can be found here.
Herein, an example of how the code works!
We are going to merge the following images in a matrix of 2x2:
In #1 I am loading the libraries required. Basically, this code use "PIL."
In #2 you need to specify the directory where your images are stored (line 16).
In #3 the most relevant is that you should understand that all images will be resized according to the first image of your directory (line 28). However, you can change it quickly.
In #4 is a loop which will add each image in a sequence. There is not much mystery here.
In #5 I create some boxes and label for my images. I think it is possible to create a loop for this. If you can improve it you are welcome to try!
In #6 The final result is showed and saved if you want (uncomment line 84).
Below the full code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
""" | |
Created on Thu Oct 20 22:19:44 2018 | |
@author: Irbin B. (Based almost totally on Evan Rosica Code) | |
""" | |
#Create a Grid/Matrix of Images | |
## 1. Import the librearies | |
import numpy as np | |
import PIL, os, glob | |
from PIL import Image, ImageDraw, ImageFont | |
from math import ceil, floor | |
## 2. Preliminaries | |
PATH = r"/Users/Irbin/Downloads/Blog" # Specify the folder where your images are | |
frame_width = 8000 # in pixels | |
images_per_row = 2 # change the number of rows | |
padding = 0 # spacing between images | |
os.chdir(PATH) # Keep the path of my files | |
images = sorted(glob.glob("*.JPG")) # sorted images, important if you have the images in a specific order | |
images = images[:] # it will take all the images in the direcotry | |
## 3. Resizing the images to standard dimensions | |
img_width, img_height = Image.open(images[0]).size # the image will be resized to the first one of the folder. You can change it! | |
sf = (frame_width-(images_per_row-1)*padding)/(images_per_row*img_width) #scaling factor | |
scaled_img_width = ceil(img_width*sf) | |
scaled_img_height = ceil(img_height*sf) | |
number_of_rows = ceil(len(images)/images_per_row) | |
frame_height = ceil(sf*img_height*number_of_rows) | |
new_im = Image.new('RGB', (frame_width, frame_height)) | |
i,j=0,0 | |
# 4. Set up the loop which will add the images in sequence | |
# The loop that will go adding images | |
for num, im in enumerate(images): | |
if num%images_per_row==0: | |
i=0 | |
im = Image.open(im) | |
im.thumbnail((scaled_img_width,scaled_img_height)) | |
y_cord = (j//images_per_row)*scaled_img_height | |
new_im.paste(im, (i,y_cord)) | |
print(i, y_cord) | |
i=(i+scaled_img_width) + padding | |
j+=1 | |
# 5. Adding labels | |
font = ImageFont.truetype('/Library/Fonts/Arial Bold.ttf', 400) # Optional (type of font) | |
box = ImageDraw.Draw(new_im) # It will add a box where a label will be located | |
## Below are the labels from A to D | |
A = (0, 0, frame_width/16, frame_height/8) | |
B = (frame_width/2, 0, frame_width/2 + frame_width/16, frame_height/8) | |
C = (0, frame_height/2, frame_width/16, frame_height/2 + frame_height/8) | |
D = (frame_width/2, frame_height/2, frame_width/2 + frame_width/16, frame_height/2 + frame_height/8) | |
box_wc = np.mean([A[0], A[2]])/2 | |
box_lc = np.mean([A[1], A[3]])/2 | |
box.rectangle(A, outline='black', fill='white') | |
box.rectangle(B, outline='black', fill='white') | |
box.rectangle(C, outline='black', fill='white') | |
box.rectangle(D, outline='black', fill='white') | |
box.text((A[0] + box_wc, A[1] + box_lc), | |
"A", font=font, fill='black') | |
box.text((B[0] + box_wc, B[1] + box_lc), | |
"B", font=font, fill='black') | |
box.text((C[0] + box_wc, C[1] + box_lc), | |
"C", font=font, fill='black') | |
box.text((D[0] + box_wc, D[1] + box_lc), | |
"D", font=font, fill='black') | |
# 6. Look and save | |
new_im.show() | |
#new_im.save("Test.png", "PNG", quality=80, optimize=True, progressive=True) |
As you can see this code can help us to save time if we need to arrange too many images, even if you are writing papers that demand merging a lot of figures.
No comments:
Post a Comment