В данной части курса PyCairo мы поговорим об обрезке и маскирующих операциях. Изображения, используемые в данном учебном материале можно скачать здесь.
Обрезка
Обрезка – это ограничение рисунка в конкретно взятой области. Это делается из соображений эффективности и для создания интересных эффектов. Метод clip() в PyCairo применяется для создания вырезки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#!/usr/bin/python from gi.repository import Gtk, GLib import cairo import math import random class Example(Gtk.Window): def __init__(self): super(Example, self).__init__() self.init_ui() self.load_image() self.init_vars() def init_ui(self): self.darea = Gtk.DrawingArea() self.darea.connect("draw", self.on_draw) self.add(self.darea) GLib.timeout_add(100, self.on_timer) self.set_title("Clipping") self.resize(300, 200) self.set_position(Gtk.WindowPosition.CENTER) self.connect("delete-event", Gtk.main_quit) self.show_all() def load_image(self): self.image = cairo.ImageSurface.create_from_png("beckov.png") def init_vars(self): self.pos_x = 128 self.pos_y = 128 self.radius = 40 self.delta = [3, 3] def on_timer(self): self.pos_x += self.delta[0] self.pos_y += self.delta[1] self.darea.queue_draw() return True def on_draw(self, wid, cr): w, h = self.get_size() if (self.pos_x < 0 + self.radius): self.delta[0] = random.randint(5, 9) elif (self.pos_x > w - self.radius): self.delta[0] = -random.randint(5, 9) if (self.pos_y < 0 + self.radius): self.delta[1] = random.randint(5, 9) elif (self.pos_y > h - self.radius): self.delta[1] = -random.randint(5, 9) cr.set_source_surface(self.image, 1, 1) cr.arc(self.pos_x, self.pos_y, self.radius, 0, 2*math.pi) cr.clip() cr.paint() def main(): app = Example() Gtk.main() if __name__ == "__main__": main() |
В данном примере мы обрежем изображение. Круг перемещается по области окна и показывает часть нашего изображения. Как если бы мы смотрели на что-то сквозь круглое отверстие.
1 2 3 |
def load_image(self): self.image = cairo.ImageSurface.create_from_png("beckov.png") |
Это основное изображение. Мы будем видеть часть этого изображения после каждого цикла таймера.
1 2 3 4 |
if (self.pos_x < 0 + self.radius): self.delta[0] = random.randint(5, 9) elif (self.pos_x > w - self.radius): self.delta[0]= -random.randint(5, 9) |
Если окружность заденет левую или правую часть окна, направление движения круга изменится случайным образом. Это касается нижней и верхней части окна.
1 |
cr.arc(self.pos_x, self.pos_y, self.radius, 0, 2*math.pi) |
Данная линия добавляет круговой путь к контексту Cairo.
1 |
cr.clip() |
Метод clip() устанавливает область обрезки. Область обрезки – это используемый путь. Этот путь был создан при помощи метода arc().
1 |
cr.paint() |
Метод paint() зарисовывает выбранный исходник внутри всей области его обрезки.
Маскировка
Перед тем как нанести исходник на поверхность, его нужно отфильтровать. Маска используется в качестве фильтра. Маска определяет, где исходник будет наноситься, а где нет. Непрозрачные части маски позволяют копировать исходник на поверхность. Прозрачные части не позволяют копировать исходник на поверхность.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#!/usr/bin/python from gi.repository import Gtk import cairo class Example(Gtk.Window): def __init__(self): super(Example, self).__init__() self.init_ui() self.load_image() def init_ui(self): darea = Gtk.DrawingArea() darea.connect("draw", self.on_draw) self.add(darea) self.set_title("Masking") self.resize(310, 100) self.set_position(Gtk.WindowPosition.CENTER) self.connect("delete-event", Gtk.main_quit) self.show_all() def load_image(self): self.ims = cairo.ImageSurface.create_from_png("omen.png") def on_draw(self, wid, cr): cr.mask_surface(self.ims, 0, 0); cr.fill() def main(): app = Example() Gtk.main() if __name__ == "__main__": main() |
В данном примере, маска определяет, где рисовать, а где не рисовать.
1 2 |
cr.mask_surface(self.ims, 0, 0); cr.fill() |
Мы используем изображение в качестве маски, таким образом, отображая его в окне.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»