Pillow图片处理

下载下来的图片太大,直接贴到网站上会打开网页时要载入半天,所以要调整下尺寸,图片数目很多的话肯定不能手工做:

from pathlib import Path
from PIL import Image
PATH = '/Users/PythonABC/Documents/imageGallery/webSiteImage'
SQUARE_FIT_SIZE = 400
# set up new folder for image with logo
imagePath = Path(PATH)
shrinkImage = imagePath.joinpath('shrinkImage')
shrinkImage.mkdir(0o777, exist_ok=True)
# Loop over all files in the working directory.
for fname in [x for x in imagePath.iterdir()if x.is_file]:
  filename = fname.name
  print(filename)
  if not (filename.endswith('.png') or filename.endswith('.jpg') or filename.endswith('.jpeg')):
    continue # skip non-image files and the logo file itself
  im = Image.open(fname)
  width, height = im.size
  # Check if image needs to be resized.
  if width > SQUARE_FIT_SIZE or height > SQUARE_FIT_SIZE:
    # Calculate the new width and height to resize to.
    if width > height:
     height = int((SQUARE_FIT_SIZE / width) * height)
     width = SQUARE_FIT_SIZE
    else:
     width = int((SQUARE_FIT_SIZE / height) * width)
     height = SQUARE_FIT_SIZE
    # Resize the image.
    print('Resizing {}...'.format(filename))
    im = im.resize((width, height))
  # Save changes.
  im.save(str(shrinkImage.joinpath(filename)))

运行一半时出错,错误提示是:OSError: cannot write mode RGBA as JPEG,搜索引擎上搜索错误提示并查看搜索结果,了解了原因,也选了一个给出的解决办法。
原来JPG格式图片不支持透明,图片的模式RGBA的四个字母表示Red、Green、Blue和Alpha,Alpha就是管透明的。可以抛弃Alpha频道,也可以把图片格式改成支持Alpha的,比如PNG。
Image对象有个方法函数convert()可以把RGRA转换成RGB,抛弃Alpha,所以保存图片前添加一条语句im = im.convert('RGB')就可以了。改后的程序:

from pathlib import Path
from PIL import Image
PATH = '/Users/Smonkey/Documents/Python/imageGallery/webSiteImage'
SQUARE_FIT_SIZE = 400
# set up new folder for image with logo
imagePath = Path(PATH)
shrinkImage = imagePath.joinpath('shrinkImage')
shrinkImage.mkdir(0o777, exist_ok=True)
# Loop over all files in the working directory.
for fname in [x for x in imagePath.iterdir()if x.is_file]:
  filename = fname.name
  print(filename)
  if not (filename.endswith('.png') or filename.endswith('.jpg') or filename.endswith('.jpeg')):
    continue # skip non-image files and the logo file itself
  im = Image.open(fname)
  width, height = im.size
  # Check if image needs to be resized.
  if width > SQUARE_FIT_SIZE or height > SQUARE_FIT_SIZE:
    # Calculate the new width and height to resize to.
    if width > height:
     height = int((SQUARE_FIT_SIZE / width) * height)
     width = SQUARE_FIT_SIZE
    else:
     width = int((SQUARE_FIT_SIZE / height) * width)
     height = SQUARE_FIT_SIZE
    # Resize the image.
    print('Resizing {}...'.format(filename))
    im = im.resize((width, height))
  print('Converting {}...'.format(filename))
  im = im.convert('RGB')
  # Save changes.
  im.save(str(shrinkImage.joinpath(filename)))

其实这段代码有个让我很头疼的地方,在于语句:shrinkImage.mkdir(0o777, exist_ok=True),本来参数exist_ok=True的作用是说如果要建立的文件夹存在也不要紧,可是一运行就出错:
TypeError: mkdir() got an unexpected keyword argument 'exist_ok',提示不认这个参数,如果把python版本3.6降到3.5就没问题,可我不想降版本,所以现在只好用:
shrinkImage.mkdir(0o777),然后就导致运行一次后再运行出现错误:
FileExistsError: [Errno 17] File exists......就是文件夹已经存在的错误。
害得我调试时运行一次,下次再运行前只好手工删除程序帮忙建好的那个文件夹。虽然也可以加个程序段自动删除文件夹,可我不是不忿么,明明有参数专门干这件事啊!!!

还没完...

后续:

建立文件夹的问题通过先判断文件夹是否存在解决的:不存在,建一个;存在,删了建一个

图片格式转换,除了拿掉alpha通道外,还可以把图片格式统一转换为png,好处就是保留了图片的alpha通道。另外判断文件夹里的文件是不是图片文件,改用判断是否集合成员解决的:

from pathlib import Path
from PIL import Image
import shutil

PATH = '/Users/Smonkey/Documents/Python/imageGallery/webSiteImage'
SQUARE_FIT_SIZE = 400


# set up new folder for image with logo
imagePath = Path(PATH)
shrinkImage = imagePath.joinpath('shrinkImage')

# shrinkImage.mkdir(0o777, exist_ok=True,)
if shrinkImage.exists():
	shutil.rmtree(str(shrinkImage))

shrinkImage.mkdir(0o777)

# Loop over all files in the working directory.
for fname in [x for x in imagePath.iterdir() if x.is_file]:

	if not fname.suffix in {'.png', '.jpg', '.jpeg'}:
		continue # skip non-image files and the logo file itself

	im = Image.open(fname)
	width, height = im.size
	# Check if image needs to be resized.
	if width > SQUARE_FIT_SIZE or height > SQUARE_FIT_SIZE:
		# Calculate the new width and height to resize to.
		if width > height:
			height = int((SQUARE_FIT_SIZE / width) * height)
			width = SQUARE_FIT_SIZE
		else:
			width = int((SQUARE_FIT_SIZE / height) * width)
			height = SQUARE_FIT_SIZE
		# Resize the image.
		print('Resizing {}...'.format(fname.name))
		im = im.resize((width, height))

	# Save changes.
	im.save(shrinkImage.joinpath(fname.stem + '.png'))