2023-08-09 19:50:10 +08:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import gi, sys, os
|
|
|
|
|
import dbus
|
|
|
|
|
import dbus.service, dbus.mainloop.glib
|
|
|
|
|
|
|
|
|
|
gi.require_version('Gtk', '3.0')
|
|
|
|
|
|
|
|
|
|
from gi.repository import Gtk, Gdk, GLib, GdkPixbuf
|
|
|
|
|
from PIL import Image, ImageFilter, ImageChops
|
|
|
|
|
|
2023-08-09 20:21:50 +08:00
|
|
|
|
app_id = 'fun.wkit.shotit'
|
2023-08-09 19:50:10 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pixbuf_to_pil(pixbuf):
|
|
|
|
|
data = pixbuf.get_pixels()
|
|
|
|
|
w = pixbuf.get_width()
|
|
|
|
|
h = pixbuf.get_height()
|
|
|
|
|
stride = pixbuf.get_rowstride()
|
|
|
|
|
mode = "RGBA" if pixbuf.get_has_alpha() else "RGB"
|
|
|
|
|
img = Image.frombytes(mode, (w, h), data, "raw", mode, stride)
|
|
|
|
|
return img
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pil_to_pixbuf(img):
|
|
|
|
|
data = []
|
|
|
|
|
for p in img.getdata():
|
|
|
|
|
data.extend(p)
|
|
|
|
|
data = bytes(data)
|
|
|
|
|
alpha = img.mode == 'RGBA'
|
|
|
|
|
w, h = img.size
|
|
|
|
|
rowstride = w * 4
|
|
|
|
|
return GdkPixbuf.Pixbuf.new_from_bytes(GLib.Bytes.new(data), GdkPixbuf.Colorspace.RGB, alpha, 8, w, h, rowstride)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_shadow(img):
|
|
|
|
|
# 加载图片并确认该图片为RGBA模式,保证透明度
|
|
|
|
|
img = pixbuf_to_pil(img).convert('RGBA')
|
|
|
|
|
w,h = img.size
|
|
|
|
|
|
|
|
|
|
w += 64
|
|
|
|
|
h += 64
|
|
|
|
|
|
|
|
|
|
shadow = Image.new('RGBA', img.size, (80,80,80,100))
|
|
|
|
|
|
|
|
|
|
new_img = Image.new('RGBA', (w,h), (0,0,0,0))
|
|
|
|
|
# new_img = Image.new('RGBA', (w,h), (255,255,255,255))
|
|
|
|
|
new_img.paste(shadow, (32, 32))
|
|
|
|
|
|
|
|
|
|
new_img = new_img.filter(ImageFilter.GaussianBlur(radius = 12))
|
|
|
|
|
new_img.paste(img, (32, 32))
|
|
|
|
|
|
|
|
|
|
return pil_to_pixbuf(new_img)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Application(Gtk.Application):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
Gtk.Application.__init__(self, application_id = app_id)
|
|
|
|
|
|
|
|
|
|
display = Gdk.Display.get_default()
|
|
|
|
|
self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def do_activate(self):
|
|
|
|
|
self.shot_the_window()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def copy(self, image):
|
|
|
|
|
|
|
|
|
|
# 写图片进剪切板
|
2023-08-09 20:21:50 +08:00
|
|
|
|
self.clipboard.clear()
|
2023-08-09 19:50:10 +08:00
|
|
|
|
self.clipboard.set_image(image)
|
|
|
|
|
self.clipboard.store()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def shot_the_window(self):
|
|
|
|
|
|
|
|
|
|
screen = Gdk.Screen.get_default()
|
|
|
|
|
win = screen.get_active_window()
|
|
|
|
|
|
|
|
|
|
width = win.get_width()
|
|
|
|
|
height = win.get_height()
|
|
|
|
|
|
|
|
|
|
# 获取窗口图像
|
|
|
|
|
image = Gdk.pixbuf_get_from_window(win, 0, 0, width, height)
|
|
|
|
|
image = add_shadow(image)
|
|
|
|
|
|
|
|
|
|
self.copy(image)
|
|
|
|
|
|
|
|
|
|
# print('截图成功...')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ApplicationService(dbus.service.Object):
|
|
|
|
|
def __init__(self, app):
|
|
|
|
|
self.app = app
|
|
|
|
|
bus_name = dbus.service.BusName(app_id, bus = dbus.SessionBus())
|
|
|
|
|
dbus.service.Object.__init__(self, bus_name, '/')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dbus.service.method(app_id)
|
|
|
|
|
def call_app(self):
|
|
|
|
|
self.app.shot_the_window()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
dbus.mainloop.glib.DBusGMainLoop(set_as_default = True)
|
|
|
|
|
bus = dbus.SessionBus()
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
obj = bus.get_object(app_id, '/')
|
|
|
|
|
obj.call_app()
|
|
|
|
|
sys.exit(0)
|
|
|
|
|
except dbus.DBusException:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app = Application()
|
|
|
|
|
app.run(sys.argv)
|
|
|
|
|
|
|
|
|
|
ApplicationService(app)
|
|
|
|
|
|
|
|
|
|
Gtk.main()
|
|
|
|
|
|