本地任意markdown工具和文件中一键插入图像(用一种优雅的方式在本地markdown文件中插入网络图片文件)

2022-10-10 11:25:53

用一种优雅的方式在markdown文件中插入图片文件

很多人用markdown语法记笔记,比如我,无论是做软件开发的时候,还是做科研笔记,我都喜欢用markdown语法来写,这是因为我习惯用git来存我的文献和笔记,而且我不喜欢使用第三方笔记软件因为命根子在别人手里(备忘录、印象笔记、有道云笔记),再者我还想轻量化且可以跨平台。所以最后就选择了markdown语法。

在网页中写markdown语法可以用丰富的文本编辑器,可以随意插入图片什么的,但是在本地写就比较蛋疼,很多编辑器不支持截图后直接插入markdown文件中,插入图片就显得比较麻烦,但是看文献做笔记的时候需要截图插入,所以就出现了这个大需求。

typora相信大家用过,可以很方便地在本地插入网络图像(前提是在typoral中配置对象存储的信息),是一个非常强大的本地md文件编辑工具。非常尴尬的是typoral开始收费了,80RMB,但是只能激活3台电脑,虽然可以反激活,但是不是账号买断制我不觉得不香,我不太喜欢,我想白嫖!

因为不想花钱买typoral,不想用盗版,又非常想要这个本地md插入网络图像的功能,所以我自己写了一个脚本,下面介绍给大家。

1. 脚本介绍

  • 这是一个python脚本,只要运行run.py然后挂在后台即可,通过设定的快捷键,触发截图功能,截完图后脚本会自动把图像上传到七牛云中,然后将图片的md地址直接设置到windows的剪切板中,截完图只需要在md文件中ctrl + v就能插入网络图像了,非常方便。
    -流程: 打开脚本 – 设置快捷键 --触发快捷键 – 截图 – 在需要的地方粘贴
    在这里插入图片描述

2. 技术手段

原理其实并不复杂:

  • 首先是截图动作和截图,截图动作使用python的wx模块,wx模块是python的GUI模块包,当我们截图时,屏幕表面的灰色蒙版层还有获取鼠标的坐标都是靠这个模块实现。而截图这个动作则是由PIL中的ImageGrab来实现,通过ImageGrab可以获取屏幕上的图像并存到某个python变量中。
  • 其次是快捷键监听,使用python的keyboard模块,里面可以设置钩子函数、监听事件等,设置完成后,当我们触发某组快捷键时,就会执行相应的程序。
  • 然后是图像上传,当我们截取完图像后,需要自动上传到网络中,我这里使用了七牛云的对象存储,如果你还不知道什么是对象存储,那你就要去七牛云官网看看了,阿里云腾讯云什么的都行吧。
  • 还有两个小玩意儿注意一下,plyer中的notification可以在windows的通知栏里面进行通知,pyperclip模块用于设置和读取windows剪切板里面的内容,相当于执行ctrl+c ctrl+v的功能。

3. 模块实现

3.1 截图实现

  • 截图的实现其实蛮简单的,使用wx模块和PIL的ImageGrab模块。(核心代码解释略)
  • 具体实现方案见代码所示。
import wxfrom PILimport ImageGrabclassScreenShot(wx.Frame):
    left,right,top,bottom=0,0,0,0
    img=Nonedef__init__(self, parent):
        wx.Frame.__init__(self, parent,
            style= wx.MAXIMIZE# 全屏显示)# 设置背景色
        self.SetBackgroundColour((255,255,255))# 设置透明度
        self.SetTransparent(30)# 注册事件
        self.Bind(wx.EVT_LEFT_DOWN, self.OnDown, self)
        self.Bind(wx.EVT_LEFT_UP, self.OnUp, self)# 显示button
        self.Show(True)defOnDown(self, event):
        pos= event.GetPosition()
        self.top= pos.y
        self.left= pos.xdefOnUp(self, event):
        pos= event.GetPosition()
        self.bottom= pos.y
        self.right= pos.x# print(self.left, self.top, self.right, self.bottom)
        self.img= self.catch_area(
            self.left, self.top, self.right, self.bottom)# 截图完毕后关闭button
        self.Close(False)defcatch_area(self, left, top, right, bottom):return ImageGrab.grab((left, top, right, bottom))

代码解析:代码的主要功能就是在屏幕上蒙上一层灰灰的层,然后鼠标按下拖拽,松开,监听拿到这两个点的坐标,拿到坐标后通过ImageGrab.grab方法截取到屏幕指定地方的截图。

  • 上面只是把工具定义好了,怎么使用呢?
from ScreenShotimport ScreenShot# import ScreenShot
app= wx.App(False)
frame= ScreenShot(None)
app.MainLoop()
frame.img.show()

3.2 七牛云上传文件

  • 打开七牛云官网,找到开发者文档,找到对象存储,然后找到python的sdk,然后复制下来改改就行了。先去把自己的对象存储开通弄好,不要嫌麻烦。
  • 我这里的文件上传小模块代码如下:

参数解释:
access_key和secret_key在哪里获取?在七牛云对象存储的开发者文档里面有详细介绍
domain是域名,如果你有自己的域名,可以像我这样配置CNAME,如果你没有域名,可以用七牛云对象存储提供的免费域名,效果一样的。
bucket_name在七牛云对象存储控制面板里面自己创建就行了

# -*- coding: utf-8 -*-# flake8: noqafrom qiniuimport Auth, put_file, etagimport qiniu.config#需要填写你的 Access Key 和 Secret Key
access_key='ifgB2xsTb2EQ94gI...'
secret_key='1QeBhytnwcwoJch4FJo...'
domain='http://paper.ruankun.xyz/'#构建鉴权对象
q= Auth(access_key, secret_key)#要上传的空间
bucket_name='iwannagraduation'#要上传文件的本地路径# localfile = './sync/bbb.jpg'# key 上传的文件名defupload(key:str, filepath:str):#上key是上传后保存的文件名# 要上传文件的本地路径
    localfile= filepath+ key#生成上传 Token,可以指定过期时间等
    token= q.upload_token(bucket_name, key,3600)
    ret, info= put_file(token, key, localfile)assert ret['key']== keyassert ret['hash']== etag(localfile)return domain+ key
  • 那么如何使用呢?在需要的地方直接调用就行了:(generate_random_str)为自定义的一个生成随机字符串的方法。
image_name= generate_random_str()+'.jpg'
image_path='./image/'# 把系统截到的图像放在本地的一个文件夹中
frame.img.save(image_path+ image_name)# 此处拿到截图后, 上传至七牛云
url= upload_qiniu.upload(image_name, image_path)# 把图像的url格式化成md中插入图片的格式
md_url='![{}]({})'.format(image_name, url)print(md_url)

3.3 windows提示框实现

  • 嘘~~莫说批话
# 用于弹出提示from plyerimport notification
notification.notify(title='阮超越的mini-typora',  \
message='剪切图片成功,地址:{}' \.format(md_url), timeout=5)

3.4 设置windows剪切板

import pyperclip
msg='我是一个没有用的人'
pyperclip.copy(msg)

3.5 通过kayboard模块设置快捷键并监听

import keyboardprint('Press and release your desired hotkey: ')
hotkey= keyboard.read_hotkey()print('Hotkey selected: ', hotkey)
keyboard.add_hotkey(hotkey, shot)
keyboard.wait()print("Press ESC to stop.")
  • 代码这么写的目的只有一个,那就是每次启动脚本都可以手动设置快捷键,写死得话万一和其它快捷键冲突,还要反复调整,比较麻烦。

3.6 整个脚本流程

  • 这一部分是整个脚本的运转,过程也不复杂,注意理解就行。
import random# python键盘监听模块import keyboard# python GUI模块import wx# 我自己写的七牛云上传文件import upload_qiniu# 操作windows剪切板import pyperclip# 七牛云, 用于上传图片import qiniu# 用于弹出提示from plyerimport notification# 屏幕截图的小脚本from ScreenShotimport ScreenShot# 生成随机字符串的函数defgenerate_random_str(randomlength=16):
    random_str=''
    base_str='ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789'
    length=len(base_str)-1for iinrange(randomlength):
        random_str+=base_str[random.randint(0, length)]return random_str# 截图操作函数defshot():
    app= wx.App(False)
    frame= ScreenShot(None)
    app.MainLoop()# 将截图保存
    image_name= generate_random_str()+'.jpg'
    image_path='./image/'
    frame.img.save(image_path+ image_name)# 此处拿到截图后, 上传至七牛云
    url= upload_qiniu.upload(image_name, image_path)
    md_url='![{}]({})'.format(image_name, url)print(md_url)
    pyperclip.copy(md_url)# 发出windows提示 上传成功了
    notification.notify(title='阮超越的mini-typora', message='剪切图片成功,地址:{}'.format(md_url), timeout=5)if __name__=='__main__':print('Press and release your desired hotkey: ')
    hotkey= keyboard.read_hotkey()print('Hotkey selected: ', hotkey)# shot回调函数
    keyboard.add_hotkey(hotkey, shot)
    keyboard.wait()print("Press ESC to stop.")


  • 作者:阮少年、
  • 原文链接:https://blog.csdn.net/ruankun521/article/details/126731069
    更新时间:2022-10-10 11:25:53