typora自定义图床实现(自定义python脚本)


Typora是我非常喜欢的Markdown编辑器,它支持“上传图像”的功能(即写文章时,插入图片自动将其上传至图床),是我们可以更快捷的分享文档,不至于每次都需要文档加图片一起发送。

网上文档多为使用IPic、uPic、PicG等软件的方式,我们需要下载软件,比较繁琐。所以我自定义了一个脚本,让工作变得更加简单。

一、原理

将本地图片上传至图床,这个过程本质上来说就是一条HTTP请求,具体流程如下

img

所以,我们只需要使用一个云服务器当服务端,本地当客户端就能够很简单的搭建我们自己的图床

二、服务端搭建

服务端项目运行与一个文件夹中,我的文件夹为/usr/local/gao/typora

image-20220715102540388

其中img为图片存储地址,img_server.log为服务端地址,img_server.py为服务端代码

需要环境:

python3

#base64
pip3 install pybase64
#flask
pip3 install flask

具体代码如下

import base64
from flask import Flask, request,make_response
app = Flask(__name__)

BASE_URL = '/'
IMG_PATH="/usr/local/gao/typora/img/" #图片实际存储地址
@app.route(BASE_URL,methods=['GET', 'POST'])
def test_post():
    #图片上传功能实现
    filename = request.form.get("filename")
    message = request.form.get("message")
    content = request.form.get("content")
    app.logger.info(message+filename)
    img = base64.urlsafe_b64decode(content)


    file = IMG_PATH+filename
    with open(file, "wb") as f:
        f.write(img)
    return "http://服务器IP:999/img/"+filename #服务器返回数据(图片访问地址)

@app.route('/img/<string:filename>', methods=['GET'])
def display_img(filename):
    #图片访问功能实现
    if request.method == 'GET':
        if filename is None:
            pass
        else:
            image_data = open(IMG_PATH+ filename, "rb").read()
            response = make_response(image_data)
            response.headers['Content-Type'] = 'image/jpg'
            return response

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=999)

需要更改内容为:

  1. 图片实际存储位置:第6行

    IMG_PATH="/usr/local/gao/typora/img/" #图片实际存储地址
    
  2. 图片返回信息

    return "http://服务器IP:999/img/"+filename #服务器返回数据(图片访问地址)
    

部署运行

  1. 到达自己的部署路径

    cd /usr/local/gao/typora 
    
  2. 运行代码

    nohup python3 img_server.py > img_server.log 2>&1 &
    

三、客户端搭建

客户端项目也运行与本地的一个文件夹中,我的文件夹为D:\softare\myScript

image-20220715103544447

其中temp为图片中间文件,用于图片压缩(占很小磁盘内存),upload_image.py为客户端代码

需要环境

python3

#base64
pip3 install pybase64
#requests
pip3 install requests
#PTL
pip3 install pillow
#其他估计系统自带

具体代码如下

import sys
import base64
import hashlib
import time
import requests
import urllib.parse
import os
from PIL import Image
from PIL import ImageFile

def compress_image(in_file, mb=1000000, quality=85, k=0.9):
    """不改变图片尺寸压缩到指定大小
    :param in_file: 压缩文件保存地址
    :param mb: 压缩目标,默认1000000byte
    :param k: 每次调整的压缩比率
    :param quality: 初始压缩比率
    :return: 压缩文件地址,压缩文件大小
    """
    o_size = os.path.getsize(in_file)  # 函数返回为字节数目
    # print('before_size:{} after_size:{}'.format(o_size, mb))
    if o_size <= mb:
        return in_file

    ImageFile.LOAD_TRUNCATED_IMAGES = True  # 防止图像被截断而报错
    temp_file="D:/softare/myScript/temp/temp."+in_file.split(".")[-1] #中间文件路径
    im = Image.open(in_file)
    try:
        im.save(temp_file)
    except Exception as e:
        print(e)

    while o_size > mb:
        im = Image.open(temp_file)
        x, y = im.size
        out = im.resize((int(x*k), int(y*k)), Image.ANTIALIAS)  # 最后一个参数设置可以提高图片转换后的质量
        try:
            out.save(temp_file, quality=quality)  # quality为保存的质量,从1(最差)到95(最好),此时为85
        except Exception as e:
            print(e)
            break
        o_size = os.path.getsize(temp_file) ##1024
    return temp_file


def main():
    target = " http://服务器IP:999"
    message = 'typora上传图片  ' #自定义上传的信息,使服务端日志更清晰 
    param = [urllib.parse.unquote(par, 'utf8') for par in sys.argv]  # 把url编码转换成中文
    param.__delitem__(0)  # 第一个参数是脚本文件本身
    if len(param) > 0:
        if not os.path.exists(param[0]):  # 通过判断第一个参数是不是文件来判断是否加了参数 ${filename}
            param.__delitem__(0)
        for i in range(0, len(param)):
            file=compress_image(param[i])#压缩图片,使其保持在1mb一下,防止访问过慢
            # file=param[i] #不压缩图片
            with open(file, "rb") as f:
                content = base64.b64encode(f.read())
                filename=str(int(time.time()))+"_"+hashlib.md5(content).hexdigest() + param[i][param[i].rfind('.'):]
                data = { 'message': message, 'content': content,'filename':filename}
                res = requests.post(target, data)
                print(res.status_code)
                if res.status_code == 200:
                    print(res.text)
                else:
                    print('Error uploading Gitee, please check')

if __name__ == '__main__':
    main()

需要更改内容为:

  1. 自己服务器的IP:第46行

    target = " http://服务器IP:999"
    
  2. 中间文件的路径:第25行

    temp_file="D:/softare/myScript/temp/temp."+in_file.split(".")[-1]#中间文件路径
    

部署运行

  1. 移动到自己的文件夹中

  2. 建temp文件夹

  3. 测试:

    python D:\softare\myScript\upload_image.py "C:\\WINDOWS\\Temp/typora-icon2.png" 
    

    如果结果类似如下则可行:

    200
    http://服务器IP:999/img/1657853679_484e0d9f4c08f524f8a9fd5892f622ff.png
    

四、typora配置

  1. 打开typora,点击 文件-偏好设置,进入设置

  2. 点击图像,进入图像设置

    image-20220715105849861

  3. 点击上传服务选择 Custom Command

    在下面命令添加

    python D:\softare\myScript\upload_image.py
    
  4. 配置图片自动上传

    1. 点击插入图片时,选择上传图片

      image-20220715110114720

    2. 勾选如下选项

      image-20220715110145382

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值