Gtk 實現圖片圓角和圓化的方法

Gtk 實現圖片圓角和圓化的方法

代碼:

#!/usr/bin/env python3
# _*_ coding: utf-8 _*_
#
#
# @File : test_round_image.py
# @Time : 2021-12-10 22:02 
# Copyright (C) 2021 WeiKeting<[email protected]>. All rights reserved.
# @Description :
#
#
import math

import gi

gi.require_version('GdkPixbuf', '2.0')
gi.require_version('Gtk', '3.0')
from gi.repository import GdkPixbuf, Gtk, Gdk


def rounded_image(fn, size=None, corner_radius=0):
    import cairo
    if size is not None and size[0] > 0 and size[1] > 0:
        piu = GdkPixbuf.Pixbuf.new_from_file_at_scale(fn, size[0], size[1], True)
    else:
        piu = GdkPixbuf.Pixbuf.new_from_file(fn)
    w = piu.get_width()
    h = piu.get_height()
    if corner_radius > 0:
        # 圓角
        r = min(corner_radius, w / 2., h / 2)
        surface = cairo.ImageSurface(cairo.Format.ARGB32, w, h)
        ctx = cairo.Context(surface)

        Gdk.cairo_set_source_pixbuf(ctx, piu, 0, 0)

        # top left 圓角
        ctx.arc(r, r, r, -math.pi, -math.pi / 2.)
        # top line
        ctx.line_to(w - r, 0)

        # top right 圓角
        ctx.arc(w - r, r, r, -math.pi / 2., 0)
        # right line
        ctx.line_to(w, -r)

        # bottom right 圓角
        ctx.arc(w - r, h - r, r, 0, math.pi / 2.)
        # bottom line
        ctx.line_to(r, h)

        # bottom left 圓角
        ctx.arc(r, h - r, r, math.pi / 2., math.pi)
        # 連接當前path的起點和重點,即left line
        ctx.close_path()

        # 創建clip(可繪製區域)
        ctx.clip()

        ctx.paint()
        piu = Gdk.pixbuf_get_from_surface(surface, 0, 0, w, h)
    else:
        # 圓邊
        sw, sh = (min(w, h),)*2
        surface = cairo.ImageSurface(cairo.Format.ARGB32, sw, sh)
        ctx = cairo.Context(surface)
        # 把原圖的pixbuf,居中顯示
        Gdk.cairo_set_source_pixbuf(ctx, piu, -(w - sh) / 2.0, -(h - sh) / 2.0)
        # 圓形path
        ctx.arc(sw / 2.0, sh / 2., sh / 2.0, 0, 2 * math.pi)
        # 以當前path(圓形),創建clip(可繪製區域)
        ctx.clip()
        # 把source(pixbuf)畫到clip中
        ctx.paint()
        piu = Gdk.pixbuf_get_from_surface(surface, 0, 0, sw, sh)
    return piu


def main():
    import sys
    f = sys.argv[1]
    pb = rounded_image(f, size=None, corner_radius=0)
    win = Gtk.Window()
    image = Gtk.Image()
    image.set_from_pixbuf(pb)
    win.add(image)
    win.set_default_size(300, 400)
    win.show_all()
    win.present()
    win.connect("delete-event", Gtk.main_quit)
    Gtk.main()


if __name__ == '__main__':
    main()

代碼雖然是python寫的,但是看一眼應該就可以寫出C語言的版本。

測試環境: Ubuntu 21.10 不過我相信支持python3和Gtk3的環境應該都能跑起來

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章