Python-сообщество
- Начало
- » GUI
- » PyQt Управление прозрачностью окна
#1 Окт. 29, 2012 22:48:59
Guljaca От: Зарегистрирован: 2011-07-11 Сообщения: 93 Репутация: 0 Профиль Отправить e-mail
PyQt Управление прозрачностью окна
Как сделать дочернее окно прозрачным, если для родителя указан фон?
self.setWindowOpacity(0.5) работает только с родителем и влияет на все дочерние окна
Фон для родителя
pal = self.palette()
pal.setBrush(QPalette.Normal,QPalette.Window,QBrush(image))
self.setPalette(pal)
Если для дочерних окон нельзя установить прозрачность, какими путями можно достичь этого же результата?
Так можно создать прозрачное дочернее окно, но как регулировать прозрачность?
pixmap = QPixmap('fon.png')
pal = self.palette()
pal.setBrush(QPalette.Normal,QPalette.Window,QBrush(pixmap))
pal.setBrush(QPalette.Inactive,QPalette.Window,QBrush(pixmap))
self.setPalette(pal)
self.setMask(pixmap.mask())
# Так работает, но тут уже готовое изображение. Я так понимаю, можно через QColor залить фон и через маску добавить прозрачность. (В теории, я не знаю как это сделать)
image = QImage('menu/fon50.png')
image = image.scaledToWidth(w.xmax/100*60)
image = image.scaledToHeight(w.xmax/100*60)
pixmap = QPixmap(image)
pal = self.palette()
pal.setBrush(QPalette.Normal,QPalette.Window,QBrush(pixmap))
pal.setBrush(QPalette.Inactive,QPalette.Window,QBrush(pixmap))
self.setPalette(pal)
self.setMask(pixmap.mask())
self.setWindowOpacity(0.5)
Отредактировано Guljaca (Окт. 30, 2012 14:26:27)
Pillow всемогущий
Oct 20, 2016 16:07 · 1076 words · 6 minute read python tutorial
Рано или поздно, но всем нам приходится работать с графикой. Заказчики просят добавить ватермарки, сделать превьюшки картинок, построить графики… В мире python для этого есть библиотека Pillow, которая действительно умеет если не всё, то очень многое.
Установка pillow
Pillow далеко не самостоятельная библиотека, ей необходима поддержка форматов сжатия файлов. Для ubuntu как правило хватает установки следующих пакетов:
$ sudo apt-get install libjpeg-dev libfreetype6-dev zlib1g-dev libpng12-dev
То есть работы с jpg, png, ttf (шрифты) и gzip (нужен для некоторых форматов). Самое главное тут разделять сам объект Image (холст), который представляет собой абстрактную картинку, от его представления на диске в виде файла. Попробуем поиграться:

from PIL import Image, ImageDraw, ImageFont def sample(): image = Image.new('RGBA', (300, 300)) draw = ImageDraw.Draw(image) draw.line(((0, 0), (150, 300)), fill=(255, 0, 0), width=20) # красная линия draw.arc(((150, 150), (250, 250)), 45, 210, fill=(0, 255, 0)) # зелёная дуга draw.rectangle(((50, 50), (150, 150)), fill=(0, 0, 255)) # синий квадрат font = ImageFont.truetype("data/kaligrafica_allfont_ru.ttf", 32) draw.text((200, 200), 'Hello world!', (255, 255, 0), font=font) # жёлтый текст image = image.rotate(90) # поворот на 90 градусов image.save('sample.png') if __name__ == "__main__": sample()
Ничего сложного — рисование примитивов и текста. Такое в жизни вряд ли пригодится, так что этот пример исключительно для ознакомления с базовыми возможностями.
Создание превью изображения
Существует куча разных библиотек для создания и хранения превьюшек картинок. В своих проектах на Django я использую sorl-thumbnail. В принципе она всем устраивает, большой плюс что она хранит ссылки на все сгенерированные изображения. Таким образом при смене основного изображения превьюшки пересоздаются заново. До недавнего времени там был критичный баг, но после небольших уговоров автор его закрыл.
Но не всегда разумно тянуть в проект такую махину. Порой хочется чего-нибудь лёгкого и простого. Например, как-то так:
im = Image.open('input.jpg') im.thumbnail((64, 64)) im.save("thumbnail.jpg", "JPEG")
Что может быть проще! 🙂 У Image ещё есть метод resize , но, в отличие от thumbnail , он не сохраняет соотношение сторон (aspect ratio). Т.е. в примере выше картинка будет ужата до 64 пикселей по большей стороне.
Наложение ватермарка
Как всегда для Django есть уже готовая библиотека, но нам же интересно самим всё сделать, правда ведь? 🙂 В качестве водяного знака возьмём вот этого котика, повёрнутого на 45 градусов. Нууу… все же любят котиков…

mark = Image.open('cat_PNG132.png') mark = mark.resize(source.size) source.paste(mark, (0, 0), mark) source.save('wm.png')
Таким вот образом можно наложить изображения друг на друга, но на водяной знак это смахивает лишь очень отдалённо. Хм, opacity 0.1, rotate 30 . Кстати, тут мы работаем с прозрачными изображениями, так что вместо обычного метода Image.paste надо использовать Image.alpha_composite — он сохраняет альфа-каналы.

mark = Image.open('cat_PNG132.png') mark = mark.resize(source.size) alpha = ImageEnhance.Brightness(mark.split()[3]).enhance(0.1) mark.putalpha(alpha) mark = mark.rotate(-30, Image.BICUBIC) Image.alpha_composite(source, mark).save("test3.png")
Склейка изображений
Ещё один пример работы с изображениями — компоновка нескольких в одно. Как пример это может быть массив спрайтов (для web) или фреймов для анимации какой-нибудь 2D игрушки (Да-да, я знаю, что велосипедов и так уже полно, и некоторые даже работают, но у них есть фатальный недостаток 🙂 ). Мне же понадобилось из картинок-элементов собрать таблицу Менделеева. Так что код из рабочего проекта:
def concat(images): width, height = images[0][0].size # size of element total_width = width * len(images[0]) max_height = height * len(images) result = Image.new('RGBA', (total_width, max_height)) # common canvas y_offset = 0 for line in images: x_offset = 0 for element in line: result.paste(element, (x_offset, y_offset)) x_offset += element.size[0] y_offset += line[0].size[1] return result

В images передаётся матрица из объектов типа Image . В первом блоке вычисляются размеры результирующего холста, а во втором вставляются картинки согласно элементам матрицы. Если будет интересно, то в комментариях могу выложить полный код по склейке таблицы Менделеева из готовых png и саму таблицу для печати.
Генерация gif
Переходим к генерации gif из получившихся картинок. Вот здесь всё несколько неочевидно. Беглое гугление говорит, что есть специальная библиотечка images2gif (только python2), однако сам автор просит её не использовать. Некоторые предлагают вызывать convert -delay 20 -loop 0 *jpg animated.gif , но что-то всё это костылями попахивает, неужели сам Pillow не умеет склеивать png в gif?! Конечно же умеет! Причём сам, без библиотеки pillow-images2gif. Пусть у нас в каталоге data/png находятся 10 файлов вида 000.png, 001.png, 002.png… Тогда склеить их в один gif можно таким кодом:
SIZE = (300, 300) # размер gif WHITE = (255, 255, 255) # фон каждого кадра gif def prepare(img): # resize to 300x300 and remove opacity bg = Image.new("RGB", SIZE, WHITE) img = img.resize(SIZE, Image.ANTIALIAS) bg.paste(img, img) return bg.convert('P', palette=Image.ADAPTIVE, dither=1) images = list(map(prepare, map(Image.open, ('data/png/.png'.format(x) for x in range(10))))) gif = Image.new('RGB', SIZE, WHITE) gif.save('temp.gif', 'GIF', save_all=True, append_images=images, loop=0) # loop=0 зацикливает воспроизведение
Это код для Python3, так что map пришлось распаковать в список. Ух, прям обожаю функциональщину — так много делается всего в одной строчке 🙂 С помощью внутреннего map создаётся итератор по списку Image для каждого файла, а потом к каждому Image применяется функция prepare. Её назначение заключается лишь в подготовке кадра — привести к одному размеру и сделать фон белым вместо прозрачного. К сожалению, иного способа кроме как положить png (переменная img) на белый холст (переменная bg) для удаления прозрачности я не нашёл. Согласен, как-то некрасиво получается… Зато потом одной командой save оно само как-то всё склеивается. Посмотреть можно здесь.
А теперь наоборот
Зачастую надо не собрать gif из картинок, а наоборот разбить (а потом, возможно, сохранить в новый gif). Pillow умеет и это:
im = Image.open("in.gif") frames = ImageSequence.Iterator(im) def resize(frames): for frame in frames: image = frame.copy() yield image.crop((0, 0, image.width, image.height - 15)) frames = resize(frames) om = next(frames) om.info = im.info om.save("out.gif", save_all=True, append_images=list(frames))

К сожалению, здесь может быть не так просто из-за формата gif. В нём каждый кадр может содержать свою собственную палитру. Это помогает в уменьшении размеров файла, но накладывает дополнительные трудности при работе с ним. Причём палитра может вычисляться как дифф от предыдущего кадра с одним “прозрачным” цветом. То есть, надо накапливать разницу цветов, учитывая ту же прозрачность, но поля этого блога слишком малы, чтобы привести решение 🙂
Вместо послесловия
Работа с графикой таким образом иногда напоминает магию, особенно когда действий несколько. Например, загрузить файл по http, преобразовать в поток байт, открыть по нему Image, повернуть/отразить/уменьшить и записать на диск. Да, это, конечно же, всего десяток строк, но провозиться с этим можно долго. Мне помогает отлаживать программы метод Image.show() , который показывает текущую картинку на экране. Можно сказать, что это своего рода println для pillow 🙂
Как всегда код на GitHub. В файле sample.py примеры к статье, в файле main.py — генерация таблицы Менделеева. Картинки, к сожалению, в открытый доступ загрузить не смогу, т.к. они отрисованы вручную дизайнером. Если интересуют именно они, пишите в личку в Telegram (@TyVik).
2010-2019 (c) TyVik
Powered by Hugo Theme By nodejh
Как выставить прозрачность у фотографии при наложении?

Все хорошо, НО появляются черные цвета там где была «пустота»
История о том как я сделал небольшую прозрачность
Но она все равно недостаточная
А как сделать сильнее я не знаю
for_test = round_rectangle((300, 60), 30, "#f2e8c9") mask = for_test.convert('L') for_test.putalpha(mask) main_image.paste(for_test, (30, 400), mask=for_test)

Фотография стала прозрачнее, но этого мало
- Вопрос задан более трёх лет назад
- 384 просмотра
Python-сообщество
![]()
- Начало
- » Python для новичков
- » Прозрачность фона виджета в Canvas tkinter
#1 Июнь 20, 2020 13:43:54
Konstantin1984+ Зарегистрирован: 2020-02-04 Сообщения: 73 Репутация: 0 Профиль Отправить e-mail
Прозрачность фона виджета в Canvas tkinter
У меня возник вопрос. Как сделать прозрачный фон у объекта Canvas (в том числе у вставленной картинки). Ведь все виджеты, по сути, вставляются в прямоугольник, имеющий фоновый цвет. В итоге если я перемещаю объект по экрану и задеваю другой объект с отличным от фона прямоугольника цветом, то проявляется фон, а хотелось бы, чтобы его не было видно. Как это сделать?
#2 Июнь 20, 2020 13:53:43
4kpt_V От: Харьков Зарегистрирован: 2017-02-19 Сообщения: 299 Репутация: 12 Профиль Отправить e-mail
Прозрачность фона виджета в Canvas tkinter
alpha=
(Windows, Mac) Controls window transparency. 0.0 means fully transparent, 1.0 means fully opaque. This isn’t supported on all systems; where not supported, Tkinter always uses 1.0. Note that in this release, this attribute must be given as “-alpha”.
Отредактировано 4kpt_V (Июнь 20, 2020 13:54:42)
#3 Июнь 20, 2020 18:47:30
Konstantin1984+ Зарегистрирован: 2020-02-04 Сообщения: 73 Репутация: 0 Профиль Отправить e-mail
Прозрачность фона виджета в Canvas tkinter
С данным материалом я знаком, но указанный параметр делает прозрачным окно и все, что в нем находится, а мне нужно сделать прозрачным фон для объекта, чтобы вне зависимости от того, с каким объектом он пересекается, или какого цвета холст, фон не был виден.
#4 Июнь 20, 2020 21:11:40
4kpt_V От: Харьков Зарегистрирован: 2017-02-19 Сообщения: 299 Репутация: 12 Профиль Отправить e-mail
Прозрачность фона виджета в Canvas tkinter
Честно. Я не пойму о чем вы.
#5 Июнь 21, 2020 10:57:14
Konstantin1984+ Зарегистрирован: 2020-02-04 Сообщения: 73 Репутация: 0 Профиль Отправить e-mail
Прозрачность фона виджета в Canvas tkinter
Скажу по-другому, есть, к примеру, картинка, на которой изображен человечек, изображен он на каком-то фоне. Я вставляю картинку в Canvas tkinter (или в pygame), и если фон картинки не совпадает по цвету с холстом, то мы видим не только человечка, но и фон. Такая же ситуация с пересечением другого объекта: фон, даже если по цвету совпадает с холстом, пересекаясь с другим объектом, становится видимым (накладывается на объект). Мне нужно чтобы было видно только человечка при любых его перемещениях по холсту. Возможно, я много хочу, и это звучит нереально, но ведь как-то это делают, правда, возможно, что в Canvas это невозможно реализовать.
#6 Июнь 21, 2020 13:55:26
PEHDOM Зарегистрирован: 2016-11-28 Сообщения: 2196 Репутация: 294 Профиль Отправить e-mail
Прозрачность фона виджета в Canvas tkinter
Konstantin1984+
Я вставляю картинку в Canvas tkinter (или в pygame), и если фон картинки не совпадает по цвету с холстом, то мы видим не только человечка, но и фон
Вообщето есть такое понятие как альфа-канал, вот его и используют для задания прозрачности.
from tkinter import Tk, Canvas from PIL import Image, ImageTk root = Tk() image = Image.open('jerry.png') tkimg = ImageTk.PhotoImage(image) canvas = Canvas(root, height=600, width=600) canvas.grid() def stamp(event): canvas.create_image(event.x, event.y, image=tkimg) canvas.bind('', stamp) root.mainloop()
[code python][/code]
Бериегите свое и чужое время.
Отредактировано PEHDOM (Июнь 21, 2020 13:55:52)

Прикреплённый файлы:
jerry.png (20,5 KБ)
