Guanlin Chen
Guanlin Chen

Reputation: 69

How to Use python to show images on a 100 by 100 grid

I have 10000 images and wanted to create a 100 by 100 grid to show the images.

EDIT:

With the code

fig, axs = plt.subplots(7,10, figsize=(100, 100))
fig.subplots_adjust(hspace = .005, wspace= .1)
axs = axs.ravel()
for i, img in enumerate(glob.glob('C:/Users/User/Desktop/Tensorflow/indicator_result/*.jpg')):
    image = cv2.imread(img)
    axs[i].axis('off')
    axs[i].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    axs[i].set_title(img[-24:-13],fontsize= 60)

I can display, in this case, 7 rolls and 10 columns image with name on top of it. Is there any way to save the whole 7 by 10 grid image to a single image? enter image description here

Upvotes: 0

Views: 1994

Answers (1)

furas
furas

Reputation: 142651

As for me it is the simplest to create HTML with <table> which has <img> and filename in every cell.

#filenames = df['FileName']
#filenames = glob.glob('*.jpg')
filenames = list(range(10000, 10200)) # (10000, 19999)

column_numbers = 10  # 100

html = '<html><body><table>'

for i, name in enumerate(filenames):
    # start row
    if i % column_numbers == 0:
        html += '<tr>'
        
    # cell in row
    html += f'<td>{name}<br/><img width="100" height="100" src="{name}"></td>'
    
    # end row
    if i % column_numbers == (column_numbers-1):
        html += '</tr>'

html += '</table></body></html>'  

and then I could save it in file and open in web browser

fh = open('output.html', 'w')
fh.write(html)
fh.close()

import webbrowser

webbrowser.open('output.html')

or I could display directly in Notebook

from IPython.display import display, HTML

display(HTML(html))

But this way it can't convert to greyscale and can't resize it.

<img> uses width="100" height="100" to display with size 100x100 but it reads full images and browser rescale them. Always it is faster to create smaller files with images 100x100 and later use only these smallers images.


Other method to create HTML with <table> is to create DataFrame with size 100x100 with all names and then use df.to_html() with formatter which will put <img> in cells

import pandas as pd

#filenames = glob.glob('*.jpg')
filenames = list(range(10000, 10200))  # (10000, 19999)

column_numbers = 10  # 100

df = pd.DataFrame()

for i in range(0, len(filenames), column_numbers):
    df = df.append( [filenames[i:i+column_numbers]] )


# formatter    
def put_img(name):
    return f'{name}<br/><img width="100" height="100" src="{name}">'

# every column needs own formatter
#all_formatters = [put_img for _ in range(column_numbers)]
all_formatters = [put_img] * column_numbers

html = df.to_html(formatters=all_formatters, escape=False, header=False, index=False)

print(html)

and now again I would save in file and open with webbrowser.open() or I would use IPython to display it directly.


EDIT:

I made example which uses subplots(rows_number, columns_number) to create grid and later I put images in cells using axs[row][col].imshow().

It automatically resize images and it can be good when you want resize window but for many images it may display very small images.

EDIT: to save it in file you can use plt.savefig('image.jpg') but it has to be before plt.show()

Doc: savefig()

import matplotlib.pyplot as plt
import glob
import math

path = 'C:/Users/User/Desktop/Tensorflow/0_180_direction_indicator/*.jpg'
filenames = glob.glob(path)

column_numbers = 5  # 100

# number of columns (width) and rows (height)
w = column_numbers
h = math.ceil(len(filenames) / column_numbers)

# create places for images
fig, axs = plt.subplots(h, w)

# remove axis for every image
for row in axs:
    for ax in row:
        ax.axis('off')

# display image
for i, name in enumerate(filenames):
    
    # calculate position 
    col = i % column_numbers
    row = i // column_numbers

    # read image
    img = plt.imread(name)
    
    # display image
    axs[row][col].imshow(img)
    
    # remove axis
    #axs[row][col].axis('off')
    
    # add title with filename without directory
    name = name.split('/')[-1] # keep only filename without directory
    axs[row][col].set_title(name)
    
# save in file - it has to be before `show()`
plt.savefig('image.jpg')

# display all 
plt.show()

Upvotes: 1

Related Questions