Django Image resizing script - python

Hi I have a project that the images upload and save in a sub folder in the media and never set an image size so now the images save 4mb and ended up totalling to 40GB in size.
I know how to write a script if the images were in a single folder but could someone guide me to do this to check all images in a folder and resize it ? Even if its in a sub folder and another sub folder.
Using Django and python
Function for image upload
def artwork_theme_name(instance, filename):
path, name = get_hashed_upload_to(instance.id, filename)
return 'theme/{}/{}'.format(path, name)
Upload model
class ArtworkForeground(models.Model):
title = models.CharField(_("title"), max_length=128)
description = models.TextField(_("description"))
foreground = models.ImageField(_("foreground image"), upload_to=artwork_theme_name)

Here I'm overwrite the existing image with reduced size image. The artwork.foreground is a file-pointer and we passed the fp to the PIL class. The save() method of Image class takes filename/path-conatining-filename as first argument. At that point the .path attribute became handy
from PIL import Image
def do_resize(image):
pil_img = Image.open(image)
resize_limit = 100, 150
pil_img.thumbnail(resize_limit, Image.ANTIALIAS)
pil_img.save(image.path)
for artwork in ArtworkForeground.objects.filter(foreground__isnull=False):
do_resize(artwork.foreground)
UPDATE-1
Where should I put this snippet?
If you set some kind of restriction or validation from Now Onwards, just run this script in your Django Shell ( This is only for a one time use)

You could use os.walk() function to go through all files and subfolders.
for (path, dirs, files) in os.walk(path):
for file in files:
filename = os.path.join(path, file)
if filename.endswith('.jpg'):
resize_image(filename)

Related

cv2.imwrite cannot work after I convert my .py file into .exe file. Is anyone can help me to solve this issue?

This is my code. It works well and able to write the image to the specified folder in IDE. But, after converting the .py file to .exe file by PyInstaller, cv2.imwrite does not work anymore. Is there anyone can help me to solve this issue?
# enter code here
import cv2
import os
# Image path
image_path = r'C:\Users\Meadow\Desktop\Saving Images\jeremy.jpg'
# Image directory
directory = r'C:\Users\Meadow\Desktop\Saving Images'
# Using cv2.imread() method to read the image
img = cv2.imread(image_path)
# Change the current directory to specified directory
os.chdir(directory)
# List files and directories in 'C:/Users/Rajnish/Desktop/GeeksforGeeks'
print("Before saving image:")
print(os.listdir(directory))
# Filename
filename = 'savedImage.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, img)
# List files and directories
# in 'C:/Users / Rajnish / Desktop / GeeksforGeeks'
print("After saving image:")
print(os.listdir(directory))
print('Successfully saved')

Efficient way to load mass amounts of images in pygame?

This is the way I've been using to do it so far.
pygame.image.load("a.png")
pygame.image.load("b.png")
pygame.image.load("c.png")
However, if I have an animation with 60 images, how do I efficiently load all of that in?
For performance reasons, you must load the files before the application loop.
One option is to load the image files and store the Surfaces in a dictionary:
import os
folder = #image folder
files = ['a.png', 'b.png', 'c.png']
images = {}
for filepath in files:
path, filename = os.path.basename(filepath)
name, ext = os.path.splitext(path)
image = pygame.image.load(os.path.join(folder, file path)).convent_ alpha()
images[name] = image
In the application loop, you can access the images by subscription:
image = images['a']

How to save processed images to different folders within a folder in python?

I have code with looks through a folder 'Images' and then subfolders and processes all those images.
I now need to save those images to a parallel directory, i.e. a folder called 'Processed Images' (in same directory as 'Images' folder) and then to the subfolders within this folder - these subfolders are named the same as the subfolders in 'Images' - the image should save to the same name of subfolder that it came from.
I can get the images to save to 'Processed Images' but not the subfolders within it.
path = ("...\\Images")
for dirName, subdirList, fileList, in os.walk(path):
for file in fileList:
full_file_path = os.path.join(dirName, file)
if file.endswith((".jpg")):
image_file = Image.open(full_file_path)
image_file = image_file.convert('L')
image_file = PIL.ImageOps.invert(image_file)
image_file = image_file.resize((28, 28))
new_filename = file.split('.jpg')[0] + 'new.png'
path2 = ("...\\Processed Images")
image_file.save(os.path.join(path2, new_filename))
else: continue
You can use the function os.mkdir() to create a new folder. dirName returned by os.walk() gives you the current folder path, so you can just extract the part of the path that you need, append it to ...\\Processed Images and create the new folder if needed.
Be sure to use two separate folder trees for the input files and output files. Otherwise os.walk() will find the new directories with the output images and continue to iterate over them.
I think you can seriously simplify this code using pathlib. I’m not sure about the triple dots (I think they should be double) in your base paths but they may work for you.
from pathlib import Path
path = Path("...\\Images")
path2 = Path("...\\Processed Images")
path2.mkdir(exist_ok=True)
for jpg_file in p.glob('**/*.jpg'):
full_file_path = str(jpg_file)
image_file = Image.open(full_file_path)
image_file = image_file.convert('L')
image_file = PIL.ImageOps.invert(image_file)
image_file = image_file.resize((28, 28))
new_filename = jpg_file.stem + 'new.png'
image_file.save(str(path2 / new_filename))

Saving images as thumbnails Python

I have this code, it origionally comes from here: renaming files base on the file structure
I added a thumbnail save as to the function from here: Create thumbnail images for jpegs with python
I'm trying to select all files from a directory structure, rename them based on the file structure. I've added a filter using 'in', but I can't get the resize as thumbnail bit to work.
Name Image is not defined.
import os
import shutil
#testing
import sys
import image
def image_thumb_filter():
size = 128, 128
for path, dirs, files in os.walk(wd):
for file in files:
if file.endswith(".jpg"):
src = os.path.join(path, file)
#print(src)
dst = os.path.join(os.getcwd(), "Photo_selection")
if not os.path.exists(dst): #Checks 'Photos_mirror' folder exists
otherwise creates
os.makedirs(dst)
new_name = src.replace(wd+'\\', '').replace('\\', '_')
new_dst = os.path.join(dst, new_name + "_thumb")
if not os.path.isfile(new_dst):
if "99\\526" in src:
try:
im = image.open(src)
im.thumbnail(size)
im.save(new_dst, "JPEG")
except IOError:
print ("cannot create thumbnail for", infile)
shutil.copy(src, dst)
old_dst = os.path.join(dst, file)
#Assuming your /dir/dir/... structure is inside of your working
directory (wd)
os.rename(old_dst, new_dst)
else: # it doesn't like this else statement
continue
image_thumb_filter()
You have not defined the object "Image" specifically anywhere in your code. Remember that Python and many other languages are case sensitive. Maybe you meant "image?"

Open images from a folder one by one using python?

Hi all I need to open images from a folder one by one do some processing on images and save them back to other folder. I am doing this using following sample code.
path1 = path of folder of images
path2 = path of folder to save images
listing = os.listdir(path1)
for file in listing:
im = Image.open(path1 + file)
im.resize((50,50)) % need to do some more processing here
im.save(path2 + file, "JPEG")
Is there any best way to do this?
Thanks!
Sounds like you want multithreading. Here's a quick rev that'll do that.
from multiprocessing import Pool
import os
path1 = "some/path"
path2 = "some/other/path"
listing = os.listdir(path1)
p = Pool(5) # process 5 images simultaneously
def process_fpath(path):
im = Image.open(path1 + path)
im.resize((50,50)) # need to do some more processing here
im.save(os.path.join(path2,path), "JPEG")
p.map(process_fpath, listing)
(edit: use multiprocessing instead of Thread, see that doc for more examples and information)
You can use glob to read the images one by one
import glob
from PIL import Image
images=glob.glob("*.jpg")
for image in images:
img = Image.open(image)
img1 = img.resize(50,50)
img1.save("newfolder\\"+image)

Categories

Resources