You have to run it in the folder with a couple images and run shuffle_all_images() and it will create new folder and randomly generate all of the values for each pixel. I think it has to do with not converting to numpy images as opposed to PIL images?, but I can't figure it out.
import random
import os.path
import PIL
import numpy
def image_shuffle(original_image):
for row in len(original_image):
for col in len(original_image[1]):
r,g,b = original_image[row][col]
r = random.randint(1,255)
g = random.randint(1,255)
b = random.randint(1,255)
original_image[row][col] = [r, g, b]
return original_image
def get_images(directory=None):
""" Returns PIL.Image objects for all the images in directory.
If directory is not specified, uses current directory.
Returns a 2-tuple containing
a list with a PIL.Image object for each image file in root_directory, and
a list with a string filename for each image file in root_directory
"""
if directory == None:
directory = os.getcwd() # Use working directory if unspecified
image_list = [] # Initialize aggregaotrs
file_list = []
directory_list = os.listdir(directory) # Get list of files
for entry in directory_list:
absolute_filename = os.path.join(directory, entry)
try:
image = PIL.Image.open(absolute_filename)
file_list += [entry]
image_list += [image]
except IOError:
pass # do nothing with errors tying to open non-images
return image_list, file_list
def shuffle_all_images(directory=None):
""" Saves a modfied version of each image in directory.
Uses current directory if no directory is specified.
Places images in subdirectory 'modified', creating it if it does not exist.
New image files are of type PNG and have transparent rounded corners.
"""
if directory == None:
directory = os.getcwd() # Use working directory if unspecified
# Create a new directory 'modified'
new_directory = os.path.join(directory, 'modified')
try:
os.mkdir(new_directory)
except OSError:
pass # if the directory already exists, proceed
#load all the images
image_list, file_list = get_images(directory)
#go through the images and save modified versions
for n in range(len(image_list)):
# Parse the filename
filename, filetype = file_list[n].split('.')
# Round the corners with radius = 30% of short side
new_image = image_shuffle(image_list[n])
#save the altered image, suing PNG to retain transparency
new_image_filename = os.path.join(new_directory, filename + '.png')
new_image.save(new_image_filename)
The image_shuffle function is wrong.
It should be:
for row in range(original_image.size[0]):
for col in range(original_image.size[1]):
r = random.randint(0,255)
g = random.randint(0,255)
b = random.randint(0,255)
original_image.putpixel((row, col), (r,g,b))
You want to have color values starting from 0 unless you don't want to get all the possible colors.
Related
I am adjusting a script.
I have 4427 images in a specified folder, named
(1).png
(2).png
(3).png
etc.
Along with those, I have another 14 images, named:
1.png
2.png
3.png
etc.
Basically the script should:
Take a specific image I tell it to open of the 4427
Then, open one of the 14 images at random
Merge the two and save it to a specified directory.
Code
import os
import random
from PIL import Image
path = r"C:\Users\17379\Desktop\images\Low effort glasses"
random_filename = random.choice([
x for x in os.listdir(path)
if os.path.isfile(os.path.join(path, x))
])
print(random_filename)
x = Image.open(r"(1).png").convert("RGBA")
y = Image.open(random_filename)
z = Image.alpha_composite(x, y)
z.save(r"C:\Users\17379\Desktop\images\Resized punks\Resized punks\punk1.png")
How to do this to all 4427 images and then save each file to the specified directory?
The pseudo-code for your task is:
for file_name in source_image_list:
# 1. Take a specific image I tell it to open of the 4427
source_image = open_source(file_name)
# 2. Then, open one of the 14 images at random
random_image = open_random_of(random_image_list)
# 3. Merge the two and save it to a specified directory.
target_image = merge(source_image, random_image)
save(target_image, file_name, directory)
Translate this to Python:
import os
import glob
import random
from PIL import Image
def open_random(random_image_list):
random_filename = random.choice(in random_image_list)
print(f"Random: {random_filename}")
return Image.open(random_filename)
def open_source(file_name):
return Image.open(file_name).convert("RGBA")
def merge(source, random):
return Image.alpha_composite(source, random)
def save(image, original_name, directory):
target = os.path.join(directory, os.path.basename(original_name))
print(f"Saving: {target}")
image.save(target)
if __name__ == '__main__':
source_path = r"C:\Users\17379\Desktop\images"
random_path = r"C:\Users\17379\Desktop\images\Low effort glasses"
directory = r"C:\Users\17379\Desktop\images\Resized punks\Resized punks"
random_image_list = os.listdir(random_path) # can also use glob here to filter for (specific) images only
source_image_list = glob.glob(f"{source_path}/\([0-9]+\).png")
for file_name in source_image_list:
print(f"Source: {file_name}")
# 1. Take a specific image I tell it to open of the 4427
source_image = open_source(file_name)
# 2. Then, open one of the 14 images at random
random_image = open_random_of(random_image_list)
# 3. Merge the two and save it to a specified directory.
target_image = merge(source_image, random_image)
save(target_image, file_name, directory)
Note: I had to replace os.listdir(source_path) for glob.glob because it accepts a regular-expression to filter for specific files only. See also
Python3 create list of image in a folder
Im trying to copy the pixel information of a group of images to a CSV, however when I try the following code, Im unable to create the csv. Is there any other way to copy the pixels to a csv?
from PIL import Image
import numpy as np
import sys
import os
import csv
# default format can be changed as needed
def createFileList(myDir, format='.png'):
fileList = []
print(myDir)
for root, dirs, files in os.walk(myDir, topdown=False):
for name in files:
if name.endswith(format):
fullName = os.path.join(root, name)
fileList.append(fullName)
return fileList
# load the original image
myFileList = createFileList('/test/surprise')
for file in myFileList:
print(file)
img_file = Image.open(file)
# img_file.show()
# get original image parameters...
width, height = img_file.size
format = img_file.format
mode = img_file.mode
# Make image Greyscale
img_grey = img_file.convert('L')
#img_grey.save('result.png')
#img_grey.show()
# Save Greyscale values
value = np.asarray(img_grey.getdata(), dtype=np.int).reshape((img_grey.size[1], img_grey.size[0]))
value = value.flatten()
print(value)
with open("imagenes.csv", 'a') as f:
writer = csv.writer(f)
writer.writerow(value)
I would like to generate a csv with the pixel information similar to FER2013.csv as can be see in the following image.
I'm writing a program that iterates over a directory of satellite images, crops each image to have a square aspect ratio (1:1), and then saves the cropped image in a different directory created at the beginning of the program. I'm able to crop each image successfully, but the cropped image is being saved to its original directory instead of the one created at the start of the program.
For example, the file path leading up to, but not including, the directory containing imagery is C:\Users\nickm\Documents\Projects\Platform\Imagery, while the directory containing the satellite imagery is dir (a subdirectory of Imagery). After each image is cropped, I want to save it to the directory created at the start of the program (e.g. 10-22-18 cropped, which will also be a subdirectory of Imagery). Instead, it's being saved in dir, overwriting the original image.
Here's my code:
# image.py
import datetime
import os
from PIL import Image
def make_new_dir(abs_path):
'''Creates the directory where our cropped imagery will be saved and
returns its absolute file path.
'''
date_obj = datetime.datetime.now()
date = date_obj.strftime('%x').replace('/', '-')
new_path = abs_path + '/' + date + ' cropped'
os.mkdir(new_path)
return new_path
def get_crop_area(image):
'''Crops each image to have a square aspect ratio (1:1) using the
image's size.
'''
image_width, image_height = image.size
diff = max(image_width, image_height) - min(image_width, image_height)
if image_width > image_height:
return [diff / 2, 0, image_width - diff / 2, image_height]
else:
return [0, diff / 2, image_width, image_height - diff / 2]
def crop_images(abs_path, image_dir, new_dir):
'''Iterates over the directory containing the satellite images
(abs_path + image_dir), cropping each image and saving it to our
new directory (the value returned from our make_new_dir function).
'''
new_dir = os.path.abspath(new_dir)
image_dir = os.path.join(abs_path, image_dir)
images = os.listdir(image_dir)
for image in images:
image_path = os.path.join(image_dir, image)
image = Image.open(image_path)
crop_area = get_crop_area(image)
cropped_image = image.crop(crop_area)
cropped_image_path = os.path.join(new_dir, image.filename)
cropped_image.save(cropped_image_path, 'JPEG')
The program is being run with run.py. abs_path and image_dir are being provided by the user at the command line and used as arguments in our make_new_dir and crop_images functions. This is what it looks like when I start my script from the command line:
C:\Users\nickm\Documents\Projects\Code\image>python run.py C:\Users\nickm\Documents\Projects\Platform\Imagery dir
Note that the absolute file path and the directory containing the images are two different command line arguments.
Here's my run.py script:
# run.py
import sys
from image import make_new_dir, get_crop_area, crop_images
if __name__ == '__main__':
filename, abs_path, image_dir = sys.argv
new_dir = make_new_dir(abs_path)
crop_images(abs_path, image_dir, new_dir)
This is the first program I've created that isn't just a basic coding exercise, so I'm wondering if I'm incorrectly implementing os.path.join. I've looked here and here for clarification, but neither employs the os module, which I'm pretty sure is where I'm encountering my issue.
Thanks in advance for any help provided.
If image.filename returns the full image path, you can get only the filename by doing this:
image_filename = os.path.basename(image.filename)
I have the following code that I thought would resize the images in the specified path
But when I run it, nothing works and yet python doesn't throw any error so I don't know what to do. Please advise. Thanks.
from PIL import Image
import os, sys
path = ('C:\Users\Maxxie\color\complete')
def resize():
for item in os.listdir(path):
if os.path.isfile(item):
im = Image.open(item)
f, e = os.path.splitext(item)
imResize = im.resize((200,200), Image.ANTIALIAS)
imResize.save(f + ' resized.jpg', 'JPEG', quality=90)
resize()
#!/usr/bin/python
from PIL import Image
import os, sys
path = "/root/Desktop/python/images/"
dirs = os.listdir( path )
def resize():
for item in dirs:
if os.path.isfile(path+item):
im = Image.open(path+item)
f, e = os.path.splitext(path+item)
imResize = im.resize((200,200), Image.ANTIALIAS)
imResize.save(f + ' resized.jpg', 'JPEG', quality=90)
resize()
Your mistake is belong to full path of the files. Instead of item must be path+item
John Ottenlips's solution created pictures with black borders on top/bottom i think because he used
Image.new("RGB", (final_size, final_size))
which creates a square new image with the final_size as dimension, even if the original picture was not a square.
This fixes the problem and, in my opinion, makes the solution a bit clearer:
from PIL import Image
import os
path = "C:/path/needs/to/end/with/a/"
resize_ratio = 0.5 # where 0.5 is half size, 2 is double size
def resize_aspect_fit():
dirs = os.listdir(path)
for item in dirs:
if item == '.jpg':
continue
if os.path.isfile(path+item):
image = Image.open(path+item)
file_path, extension = os.path.splitext(path+item)
new_image_height = int(image.size[0] / (1/resize_ratio))
new_image_length = int(image.size[1] / (1/resize_ratio))
image = image.resize((new_image_height, new_image_length), Image.ANTIALIAS)
image.save(file_path + "_small" + extension, 'JPEG', quality=90)
resize_aspect_fit()
In case you want to keep the same aspect ratio of the image you can use this script.
from PIL import Image
import os, sys
path = "/path/images/"
dirs = os.listdir( path )
final_size = 244;
def resize_aspect_fit():
for item in dirs:
if item == '.DS_Store':
continue
if os.path.isfile(path+item):
im = Image.open(path+item)
f, e = os.path.splitext(path+item)
size = im.size
ratio = float(final_size) / max(size)
new_image_size = tuple([int(x*ratio) for x in size])
im = im.resize(new_image_size, Image.ANTIALIAS)
new_im = Image.new("RGB", (final_size, final_size))
new_im.paste(im, ((final_size-new_image_size[0])//2, (final_size-new_image_size[1])//2))
new_im.save(f + 'resized.jpg', 'JPEG', quality=90)
resize_aspect_fit()
Expanding on the great solution of #Sanjar Stone
for including subfolders and also avoid DS warnings you can use the glob library:
from PIL import Image
import os, sys
import glob
root_dir = "/.../.../.../"
for filename in glob.iglob(root_dir + '**/*.jpg', recursive=True):
print(filename)
im = Image.open(filename)
imResize = im.resize((28,28), Image.ANTIALIAS)
imResize.save(filename , 'JPEG', quality=90)
This code just worked for me to resize images..
from PIL import Image
import glob
import os
# new folder path (may need to alter for Windows OS)
# change path to your path
path = 'yourpath/Resized_Shapes' #the path where to save resized images
# create new folder
if not os.path.exists(path):
os.makedirs(path)
# loop over existing images and resize
# change path to your path
for filename in glob.glob('your_path/*.jpg'): #path of raw images
img = Image.open(filename).resize((306,306))
# save resized images to new folder with existing filename
img.save('{}{}{}'.format(path,'/',os.path.split(filename)[1]))
For those that are on Windows:
from PIL import Image
import glob
image_list = []
resized_images = []
for filename in glob.glob('YOURPATH\\*.jpg'):
print(filename)
img = Image.open(filename)
image_list.append(img)
for image in image_list:
image = image.resize((224, 224))
resized_images.append(image)
for (i, new) in enumerate(resized_images):
new.save('{}{}{}'.format('YOURPATH\\', i+1, '.jpg'))
Heavily borrowed the code from #Sanjar Stone. This code work well in Windows OS.
Can be used to bulky resize the images and assembly back to its corresponding subdirectory.
Original folder with it subdir:
..\DATA\ORI-DIR
├─Apolo
├─Bailey
├─Bandit
├─Bella
New folder with its subdir:
..\DATA\NEW-RESIZED-DIR
├─Apolo
├─Bailey
├─Bandit
├─Bella
Gist link: https://gist.github.com/justudin/2c1075cc4fd4424cb8ba703a2527958b
from PIL import Image
import glob
import os
# new folder path (may need to alter for Windows OS)
# change path to your path
ORI_PATH = '..\DATA\ORI-DIR'
NEW_SIZE = 224
PATH = '..\DATA\NEW-RESIZED-DIR' #the path where to save resized images
# create new folder
if not os.path.exists(PATH):
os.makedirs(PATH)
# loop over existing images and resize
# change path to your path
for filename in glob.glob(ORI_PATH+'**/*.jpg'): #path of raw images with is subdirectory
img = Image.open(filename).resize((NEW_SIZE,NEW_SIZE))
# get the original location and find its subdir
loc = os.path.split(filename)[0]
subdir = loc.split('\\')[1]
# assembly with its full new directory
fullnew_subdir = PATH+"/"+subdir
name = os.path.split(filename)[1]
# check if the subdir is already created or not
if not os.path.exists(fullnew_subdir):
os.makedirs(fullnew_subdir)
# save resized images to new folder with existing filename
img.save('{}{}{}'.format(fullnew_subdir,'/',name))
Expanded the answer of Andrei M. In order to only change the height of the picture and automatically size the width.
from PIL import Image
import os
path = "D:/.../.../.../resized/"
dirs = os.listdir(path)
def resize():
for item in dirs:
if item == '.jpg':
continue
if os.path.isfile(path+item):
image = Image.open(path+item)
file_path, extension = os.path.splitext(path+item)
size = image.size
new_image_height = 190
new_image_width = int(size[1] / size[0] * new_image_height)
image = image.resize((new_image_height, new_image_width), Image.ANTIALIAS)
image.save(file_path + "_small" + extension, 'JPEG', quality=90)
resize()
If you want to resize any image from a folder where without images files, other files also exist, then you can try this:
from genericpath import isdir
from PIL import Image
import os, sys
path = "C://...//...//....//...//"
save_path = "C://...//..//...//...//"
images = os.listdir(path)
if not os.path.isdir(save_path):
os.makedirs(save_path)
for image in images:
image_path = os.path.join(path, image)
iamge_save_path = os.path.join(save_path, image)
if image.split(".")[1] not in ["jpg", "png"]:
continue
if os.path.exists(image_path):
im = Image.open(image_path)
image_resized = im.resize((224,224))
image_resized.save(iamge_save_path, quality=90)
# print("saved")
Safer to use pathlib
As jwal commented on a similar question, use the object-oriented counterparts for os of pathlib:
p = Path('images') to define the path instance (here as directory relative to current)
Path.iterdir() to find files in the path instance
Path.absolute() to get the absolute-path for file-IO functions
Path.joinpath(*other) to add subfolders or filenames
Path.mkdir(parents=True, exist_ok=True)
Path.name to return the basename of the file (like picture.png)
from pathlib import Path
# folder = 'images'
# new_dimension = (width, height)
def resize(folder, new_dimension, new_subdir):
images_folder = Path(folder)
for child in images_folder.iterdir():
print("Found image:", child)
image_path = child.absolute()
image = Image.open(image_path)
resized_image = image.resize() # could also add Image.ANTIALIAS
# create if the subdir not exists
subdir = images_folder.join(new_subdir)
if not subdir.exists():
subdir.mkdir(parents=True, exist_ok=True)
to_path = subdir.joinpath(child.name) # join adds the path-separators
print("Saving resized to:", to_path)
resized_image.save(to_path) # could also add save-options like 'JPEG', quality=90
New to coding and don't understand the error I am getting. Included below is my code and the traceback:
import PIL
import matplotlib.pyplot as plt # single use of plt is commented out
import os.path
import PIL.ImageDraw
import PIL
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
def round_corners(original_image, percent_of_side):
""" Rounds the corner of a PIL.Image
original_image must be a PIL.Image
Returns a new PIL.Image with rounded corners, where
0 < percent_of_side < 1
is the corner radius as a portion of the shorter dimension of original_image
"""
font = ImageFont.truetype("arial.ttf", 15)
# Opening the file gg.png
imageFile = ("new.jpg")
im1=Image.open(imageFile)
# Drawing the text on the picture
draw = ImageDraw.Draw(im1)
draw.text((0,0), "SAMSUNG",(0,0,255),font=font)
im1.save("marked_image.png")
#set the radius of the rounded corners
width, height = original_image.size
radius = int(percent_of_side * min(width, height)) # radius in pixels
###
#create a mask
###
#start with transparent mask
rounded_mask = PIL.Image.new('RGBA', (width, height), (127,0,127,0))
drawing_layer = PIL.ImageDraw.Draw(rounded_mask)
# Overwrite the RGBA values with A=255.
# The 127 for RGB values was used merely for visualizing the mask
# Draw two rectangles to fill interior with opaqueness
drawing_layer.polygon([(radius,0),(width-radius,0),
(width-radius,height),(radius,height)],
fill=(127,0,127,255))
drawing_layer.polygon([(0,radius),(width,radius),
(width,height-radius),(0,height-radius)],
fill=(127,0,127,255))
#Draw four filled circles of opaqueness
drawing_layer.ellipse((0,0, 2*radius, 2*radius),
fill=(0,127,127,255)) #top left
drawing_layer.ellipse((width-2*radius, 0, width,2*radius),
fill=(0,127,127,255)) #top right
drawing_layer.ellipse((0,height-2*radius, 2*radius,height),
fill=(0,127,127,255)) #bottom left
drawing_layer.ellipse((width-2*radius, height-2*radius, width, height),
fill=(0,127,127,255)) #bottom right
# Uncomment the following line to show the mask
# plt.imshow(rounded_mask)
# Make the new image, starting with all transparent
result = PIL.Image.new('RGBA', original_image.size, (0,0,0,0))
result.paste(original_image, (0,0), mask=rounded_mask)
return result
def get_images(directory=None):
""" Returns PIL.Image objects for all the images in directory.
If directory is not specified, uses current directory.
Returns a 2-tuple containing
a list with a PIL.Image object for each image file in root_directory, and
a list with a string filename for each image file in root_directory
"""
if directory == None:
directory = os.getcwd() # Use working directory if unspecified
image_list = [] # Initialize aggregaotrs
file_list = []
directory_list = os.listdir(directory) # Get list of files
for entry in directory_list:
absolute_filename = os.path.join(directory, entry)
try:
image = PIL.Image.open(absolute_filename)
file_list += [entry]
image_list += [image]
except IOError:
pass # do nothing with errors tying to open non-images
return image_list, file_list
def round_corners_of_all_images(directory=None):
""" Saves a modfied version of each image in directory.
Uses current directory if no directory is specified.
Places images in subdirectory 'modified', creating it if it does not exist.
New image files are of type PNG and have transparent rounded corners.
"""
if directory == None:
directory = os.getcwd() # Use working directory if unspecified
# Create a new directory 'modified'
new_directory = os.path.join(directory, 'modified')
try:
os.mkdir(new_directory)
except OSError:
pass # if the directory already exists, proceed
#load all the images
image_list, file_list = get_images(directory)
#go through the images and save modified versions
for n in range(len(image_list)):
# Parse the filename
filename, filetype = file_list[n].split('.')
# Round the corners with radius = 30% of short side
new_image = round_corners(image_list[n],.30)
#save the altered image, suing PNG to retain transparency
new_image_filename = os.path.join(new_directory, filename + '.png')
new_image.save(new_image_filename)
There is the full code and here is the traceback:
IOError Traceback (most recent call last)
<ipython-input-19-8a0b83840aa4> in <module>()
----> 1 round_corners_of_all_images()
C:\Users\ewainscott2019\Desktop\Computer Science\Semester 2\Image Artist\Image Artist Code.py in round_corners_of_all_images(directory)
124
125 # Round the corners with radius = 30% of short side
--> 126 new_image = round_corners(image_list[n],.30)
127 #save the altered image, suing PNG to retain transparency
128 new_image_filename = os.path.join(new_directory, filename + '.png')
C:\Users\ewainscott2019\Desktop\Computer Science\Semester 2\Image Artist\Image Artist Code.py in round_corners(original_image, percent_of_side)
20 # Opening the file gg.png
21 imageFile = ("new.jpg")
---> 22 im1=Image.open(imageFile)
23
24 # Drawing the text on the picture
C:\Users\ewainscott2019\AppData\Local\Enthought\Canopy\User\lib\site-packages\PIL\Image.pyc in open(fp, mode)
2270 filename = str(fp.resolve())
2271 if filename:
-> 2272 fp = builtins.open(filename, "rb")
2273
2274 try:
IOError: [Errno 2] No such file or directory: 'Phone_1.jpg'
I don't understand my error I have in the code. I have tried receiving help elsewhere but cannot find out anything. This is a school project that is overdue and I need to get it done.