from PIL import Image img = Image.new(mode, size, color=0)
mode
- режим, который будет использоваться для нового изображения (L
, RGB
, CMYK
и т.д.)size
- двойной кортеж, содержащие ширину и высоту в пикселях (width, height)
.color=0
- цвет заливки изображения. По умолчанию черный. Если указано, то это должно быть одно целое число или значение с плавающей запятой для одноканальных режимов и кортеж для многоканальных режимов (одно значение на каждый канал). При создании изображений RGB можно использовать строки с цветовым хешем. Если выбран цвет None
, то изображение не инициализируется.Image
Функция Image.new()
модуля Pillow
создает новое изображение с заданным режимом mode
и размером size
.
from PIL import Image, ImageDraw, ImageFont from random import choice, randint # генерируем набор цифр и букв для капчи code = ''.join([choice('QERTYUPLKJHGFDSAZXCVBN23456789') for i in range(5)]) # размеры капчи width = 200 height = 100 # создаем фон для капчи img = Image.new('RGB', (width, height), '#ffffff') draw = ImageDraw.Draw(img) # создаем фоновый шум из 40 линий for i in range(40): draw.line([(randint(0, width), randint(0, height)), (randint(0, width), randint(0, height))], randint(0, 255), 2) # положение первой буквы x=0; y=12; # подключаем font font = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 50) # добавляем набор цифр и букв for let in code: # расчеты, связанные с положением буквы if x == 0: x = 5 else: x = x + width/5 y = randint(3, 55) # добавляем цифру/букву draw.text((x, y), let, font=font, # цвет генерируем случайным образом fill=(randint(0, 200), randint(0, 200), randint(0, 200))) # сохраняем капчу img.save('capcha.jpg', 'JPEG')
Дополнительно смотрите как эту капчу можно привязать к сайту на Flask.
from PIL import Image, ImageDraw # параметры анимации frame = 10 width = 200 center = width // 2 max_radius = int(center * 1.5) fill = '#fbceb1' color = '#b3b1fb' frames = [] for i in range(0, max_radius, frame): # создаем изображения для GIF фреймов img = Image.new('P', (width, width), fill) draw = ImageDraw.Draw(img) draw.ellipse((center - i, center - i, center + i, center + i), fill=color) frames.append(img) # сохраняем GIF изображение frames[0].save('circle.gif', save_all=True, loop=0, append_images=frames[1:], optimize=False, duration=3)
Дополнительно смотрите материал Обработка GIF изображений в Pillow в Python.
Если исходные фотографии имеют разный размер, то сложность их объединения в один постер заключается в вычислении размера фонового изображения и правильном расположении фото на созданном фоне.
Для того, чтобы привести фотографии к одинаковым размерам можно использовать инструменты обрезки фото Image.crop()
и/или изменения размера Image.resize()
.
Чтобы сделать рамку для каждой фотографии на постере. Для этого есть 2 пути:
ImageOps.expand(photo, border=2, fill='#ffffff')
, а потом получить новый размер для расчета размера постера. В этом случае рамка между фото будет двойная: 4px. Что бы было красиво, необходимо сдвигать фото на 2px при наложении, и следовательно правая рамка окажется больше. img1_size[0] + img2_size[0] + 2px
. В этом случае при наложении нужно будет сдвигать фото на размер рамки: отступ у второй фотографии будет img01size[0] + 2. Пример объединения фотографий в постер, если они имеют одинаковый размер:
from PIL import Image, ImageOps # допустим есть 4 картинки одинакового размера img_size = (800, 600) for i in range(4): img = Image.new('RGB', img_size, '#82675e') img.save(f'img-{i}.jpg', 'JPEG') # Открываем картинки img1 = Image.open('img-0.jpg') img2 = Image.open('img-1.jpg') img3 = Image.open('img-2.jpg') img4 = Image.open('img-3.jpg') # получаем размеры картинок img1_size = img1.size img2_size = img2.size img3_size = img2.size img2_size = img2.size # рамка для картинок на постере border = 4 # если картинки одинакового размера, то # ширина фона => img1_size[0] * 2 + border # высота фона => img1_size[1] * 2 + border # следовательно размер фонового изображения new_img_size = (img1_size[0] * 2 + border, img1_size[1] * 2 + border) # создаем фоновое изображение размером `new_img_size` img = Image.new('RGB', new_img_size, '#ffffff') # вставляем картинки в фоновое изображение # отступ у первой картинки (0, 0) img.paste(img1, (0, 0)) # отступ у второй картинки (img_01_size[0] + 2, 0) img.paste(img2, (img1_size[0] + border, 0)) # и т. д. img.paste(img3, (0, img1_size[1] + border)) img.paste(img4, (img1_size[0] + border, img1_size[1] + border)) # в конце создадим белую рамку вокруг постера на 2px толще img = ImageOps.expand(img, border=border+2, fill='#ffffff') # сохраняем новое изображение img.save('merge_img.jpg', 'JPEG')