简体   繁体   English

如何使用 PIL 将文件夹中的多个图像裁剪为圆形?

[英]How to crop multiple images in a folder to a circular shape using PIL?

I have a folder of images and I want to crop them in a circular shape.我有一个图像文件夹,我想将它们裁剪成圆形。

This is the original image:这是原始图像:

原始图像

The result that I want is this:我想要的结果是这样的:

期望的结果

My code is:我的代码是:

import os
import glob
from PIL import Image, ImageDraw, ImageFilter
import numpy as np

def mask_circle_solid(pil_img, background_color, blur_radius, offset=0):
    background = Image.new(pil_img.mode, pil_img.size, background_color)

    offset = blur_radius * 2 + offset
    mask = Image.new("L", pil_img.size, 0)
    draw = ImageDraw.Draw(mask)
    draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset),         fill=255)
    mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))

    return Image.composite(pil_img, background, mask)

def mask_circle_transparent(pil_img, blur_radius, offset=0):
    offset = blur_radius * 2 + offset
    mask = Image.new("L", pil_img.size, 0)
    draw = ImageDraw.Draw(mask)
    draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
    mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))

    result = pil_img.copy()
    result.putalpha(mask)

    return result

def crop_max_square(pil_img):
    return crop_center(pil_img, min(pil_img.size), min(pil_img.size))

def crop_center(pil_img, crop_width, crop_height):
    img_width, img_height = pil_img.size
    return pil_img.crop(((img_width - crop_width) // 2,
                     (img_height - crop_height) // 2,
                     (img_width + crop_width) // 2,
                     (img_height + crop_height) // 2))


im = []

for f in glob.iglob("./*.jpg"):
    im.append(np.asarray(Image.open(f)))
thumb_width = 150

im = np.array(im)

list_files = os.listdir(".")
list_files.sort()
list_files.remove("Test.py")
list_files.remove(".DS_Store")

for i in range(0,len(im)):
    im_square[i] = crop_max_square(im[i]).resize((thumb_width, thumb_width), Image.LANCZOS)
    im_thumb[i] = mask_circle_transparent(im_square[i], 4)
    im_thumb[i].save(list_files[i])

I have used the functions from this article:我已经使用了这篇文章中的函数:

Generate square or circular thumbnail images with Python, Pillow 使用 Python、Pillow 生成方形或圆形缩略图

But I get this error:但我得到这个错误:

line 30, in crop_max_square
    return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
TypeError: 'int' object is not iterable

I'm not sure if you really need to use numpy to load the files, but you can do what the "Sample code for batch processing" of the page you shared does:我不确定您是否真的需要使用 numpy 来加载文件,但您可以执行 共享页面的“批处理示例代码”的操作:

import os
import glob
from PIL import Image, ImageDraw, ImageFilter


def mask_circle_solid(pil_img, background_color, blur_radius, offset=0):
    background = Image.new(pil_img.mode, pil_img.size, background_color)

    offset = blur_radius * 2 + offset
    mask = Image.new("L", pil_img.size, 0)
    draw = ImageDraw.Draw(mask)
    draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
    mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))

    return Image.composite(pil_img, background, mask)


def mask_circle_transparent(pil_img, blur_radius, offset=0):
    offset = blur_radius * 2 + offset
    mask = Image.new("L", pil_img.size, 0)
    draw = ImageDraw.Draw(mask)
    draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
    mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))

    result = pil_img.copy()
    result.putalpha(mask)

    return result


def crop_max_square(pil_img):
    return crop_center(pil_img, min(pil_img.size), min(pil_img.size))


def crop_center(pil_img, crop_width, crop_height):
    img_width, img_height = pil_img.size
    return pil_img.crop(((img_width - crop_width) // 2,
                         (img_height - crop_height) // 2,
                         (img_width + crop_width) // 2,
                         (img_height + crop_height) // 2))


im = []
jpgs_files_path = "./" # Replace the "./" path by the path where the .jpg images are.
files = glob.glob(os.path.join(jpgs_files_path, '*.jpg')) 
thumb_width = 150

for f in files:
    im = Image.open(f)
    im_thumb = crop_max_square(im).resize((thumb_width, thumb_width), Image.LANCZOS)
    im_thumb = mask_circle_transparent(im_thumb, 4)
    ftitle, fext = os.path.splitext(os.path.basename(f))
    im_thumb.save(os.path.join("./dstdir/", ftitle + '_thumbnail.png'), quality=95)

As JPG does not support transparency you need to discard the Alpha Channel or save as something that supports transparency like PNG.由于 JPG 不支持透明度,您需要丢弃 Alpha 通道或另存为支持透明度的内容,如 PNG。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM