Reputation: 69
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?
Upvotes: 0
Views: 1994
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