Есть ли другой способ залить область вне повернутого изображения белым цветом?'fillcolor' не работает со старыми версиями Python - PullRequest
1 голос
/ 26 июня 2019

Я хочу повернуть черно-белое изображение.Я пытаюсь использовать функцию поворота следующим образом:

image.rotate(angle, fillcolor=255)

Мне требуются более старые версии Python и Pillow, и они не поддерживают аргумент 'fillcolor'.Я не могу выполнить обновление до более новых версий из-за определенных ограничений и не могу использовать какие-либо внешние библиотеки.

Есть ли другой способ заполнить область за пределами повернутого изображения белым цветом с помощью подушки?

Повернутое изображениеимеет черный цвет в области вне повернутой части.Я хочу заполнить его белым цветом.

Оригинал: Исходное изображение

Поворот: Поворот изображения

Ответы [ 3 ]

2 голосов
/ 26 июня 2019

Вы можете попробовать интерполировать исходное изображение с обрезанным с помощью Image.composite () , чтобы избавиться от черных полос / границ.

from PIL import Image

img = Image.open(r"Image_Path").convert("RGBA")

angle = 30

img = img.rotate(angle)

new_img = Image.new('RGBA', img.size, 'white')

Alpha_Image = Image.composite(img, new_img, img)

Alpha_Image = Alpha_Image.convert(img.mode)

Alpha_Image.show()

Приведенный выше код принимает изображение, преобразует его в режим RGBA (для этого процесса требуется альфа), а затем поворачивает изображение на 30 градусов . После этого он создает пустой объект Image в режиме RGBA того же размера, что и исходное изображение, причем каждый пиксель имеет значение по умолчанию 255 для каждого канала (т. Е. Pure white для RGB и Full Непрозрачность в контексте Альфа / Прозрачность). Затем интерполирует исходное изображение с этим пустым, используя маску исходного изображения (мы используем маску прозрачности первого изображения). Это приводит к желаемым изображениям, где черные полосы / края заменяются белыми. В итоге мы конвертируем цветовое пространство изображения в исходное.

ОРИГИНАЛЬНОЕ ИЗОБРАЖЕНИЕ: -

enter image description here

ИЗОБРАЖЕНИЕ ПОСЛЕ ВРАЩЕНИЯ 30 Градусов: -

enter image description here

0 голосов
/ 26 июня 2019

Неловкий вариант, который всегда работал для меня, поскольку мои инструменты всегда дают светло-серую «рамку» вокруг повернутого изображения, мешающую заполнению:

  • добавить рамку на не повернутом изображении и использовать цвет заливки с этой рамкой. Граничная операция без потерь, и заполнение будет точным (и простым).

  • повернуть границу изображения. Теперь шов также будет правильным (но не точным, если вы повернуть на 45 ° или 90 °).

  • рассчитать размер повернутой границы с помощью тригонометрии. Результат не будет точным (т. Е. «131,12 пикселя»). Обычно вы можете сделать это в обратном порядке, начиная с точной границы на повернутом изображении и вычисляя границу, которую нужно добавить, и отрегулируйте ширину границы так, чтобы не повернутая граница была точной. Пример: с повернутой границей в 170 пикселей вы получите не повернутую границу в 140,3394 пикселей. Таким образом, вы используете повернутую границу 510 пикселей, в результате чего вам нужно добавить не повернутую границу 421,018 пикселей. Это достаточно близко к 421 пикселю, что приемлемо.

  • удалить повернутую границу.

Это также помогает избежать появления некоторых артефактов рядом с обрезанными частями изображения, которые падают с повернутого изображения.

Недостатком является то, что в результате вы получаете более массивную ротацию, более высокие затраты памяти и время вычислений, особенно если вы используете большие границы для повышения точности.

0 голосов
/ 26 июня 2019

Редактировать: поскольку внешние библиотеки не разрешены, я бы предложил обрезать прямоугольник, который вы хотите, и вставить его на исходное изображение, это можно сделать с помощью магических чисел (из координат прямоугольника), это работает для меня (вы можете надо немного подправить)

im = Image.open("mFul4.png")
rotated = im.rotate(105)
box = (55, 65,200,210)
d = rotated.crop(box=box)
im.paste(d, box=box)
im.save("ex.bmp" )

и вывод

enter image description here

Edit2: это самый уродливый способ, но он работает, вам может понадобиться немного подправить магические числа, чтобы сделать его более точным, я работал над вашим заданным изображением, поэтому не мог сказать, когда переусердствую , Выдает тот же результат

from PIL import Image
im = Image.open("mFul4.png")
angle=105
cos = 0.240959049 # -cos(angle)
d = im.rotate(angle)
pix = d.load()

tri_x = 120
for i in range(4): # 4 triangles
    for j in range(tri_x, -1, -1):
        for k in range(int((tri_x-j)*cos)+1, -1, -1):
            x,y =( j, k )if i <1 else (d.size[0]-j-1, d.size[1]-k-1)
            if i in [2,3]:
                y, x = (d.size[0] - j-2 , k) if i <3 else (j, d.size[1] - k)
            pix[x,y] = (255, 255, 255, 255)
d.show()
...