背景:

由于经常写markdown,需要载入的图片比较多

图片存放的方式有两种:本地和图床。放在本地有很强的私密性,但是缺点是:不同设备上编辑或不同的编辑器中编辑文档时,会遇到图片库路径的问题,每次设置都要设置还挺麻烦的。

图床就为了解决这个问题:只要上传到图床,拿到固定的url,就可以无需关心图片的存放路径,在任意的设备和文档中引用,非常方便。并且如果直接用markdown发布博客,不仅能节省上传图片的步骤,还能减轻服务器图片浏览的负载。那图床的缺点就是:

  1. 私密性,任何人只要拿到url就可以看到图片,所以没有私密性可言。

  2. 稳定性,如果云端一旦倒了,或者被墙那么对用户来说是个很大的灾难,所以除了备份好数据,选择可靠的图床也是很重要的。

我选用的图床是SM.MS,最早我是在v2ex看到,后来在很多网站和平台推荐,很好用也很稳定,支持多种url格式输出,国内有CDN加速,加载速度比较快。

但是由于没有客户端,每次打开网页上传比较麻烦,而且如果二次添加图片的话结果会被追加到最后,容易乱。于是我就想找一个客户端,能轻松调用api,实现快速的图片上传。

我找到一些第三方工具:

PicGo

PicGo 是一款基于Electron 开发的开源图床上传客户端,支持多种图床,在github上有8k多的start。但是我测试了多次,发现我无法成功上传图片,原因是有些图床不支持了:

虽然smms有插件,但是需要输入token(在smms官网注册后可获得,并且注册后有拥有后台管理的界面,可以删除上传成功的图片),但是我不想用个人的账户,用免费的api就很开心了。

因此,PicGo也就不能用了。

MarkText

Mark Text 是最喜欢的三个Windows Markdown编辑器之一(另外两个是Typora, Boostnote),而在编写md的时候,其实是可以选择几种方式:

  1. 本地保存

  2. smms图床

  3. github图床

打开 设置 > File > Preferences:

选择 Image Uploader, 选择 SM.MS的选项卡,勾选同意条款,点击 Set as default 按钮:

选择 Image选项卡,选择默认将图片上传到云端(第二个和第三个选项则是以绝对和相对路径引用本地图片):

设置完成后,只需要编辑md的时候,将图片拖入即可完成图片的上传:

但是遗憾是,我还是遇到了报错:

Snipaste_2020-04-14_14-39-17.png

Python

环境依赖:

python 3.x

Windows 10

尝试了多次的失败之后,我打算直接利用python模拟post请求,拿到请求结果,直接解析出url。本来打算用pyside2做个gui,但是发现用命令行更为快速,就放弃了。

分析的结果很简单,先用charles抓包:

然后用python构造post请求:

代码如下:

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
# coding=utf-8
# @time 2020-04-13 172249
# @author Monkey_Quake
# @function SMMS图床上传助手
# @debug

import requests
import json
import time
import os
import pyperclip


# 忽略ssl警告
requests.packages.urllib3.disable_warnings()

URL = {
'upload': 'https://sm.ms/api/v2/upload',
}

class Uploader():
def __init__(self):
pass


# 提交图片
def upload_img(self, img):
print('> Images Uploading...')
res_json = {}
# 读取文件
suffix = img.split('.')[-1].lower()
if suffix == 'jpg' or 'jpeg':
img_type = 'image/jpeg'
elif suffix == 'png' :
img_type = 'image/png'
imgfile = {'smfile': (img, open(img, 'rb'), img_type), 'file_id': '0'}
try:
res = requests.post(URL['upload'], files=imgfile, verify=False, timeout=10)
res_json = json.loads(res.text)
except Exception as e:
print('> upload_img >' + e.__class__.__name__ + ': ' + str(e))
# print(res_json)
return res_json


# 处理结果
def res_process(self, res_json):
# print(res_json)
if res_json.__contains__('success'):
# 首次上传
if res_json['success']:
url_img = '![](' + res_json['data']['url'] +')'
# 非首次上传
else:
url_img = '![](' + res_json['images'] +')'
pyperclip.copy(url_img)
print('> ' + url_img)
print('> Success: url is copied to clipboard!\n')
return True
else:
print('> Error: json is error!\n')
return False


if __name__ == "__main__":
up1 = Uploader()
while True:
path_img = input('> Input the path of image:')
res_json = up1.upload_img(path_img)
# 如果上传成功则删除图片
if up1.res_process(res_json):
os.remove(path_img)

实现的功能有:

  1. 输入图片的路径,上传图片到smms

  2. 返回url,封装成markdown的url

  3. 删除成功上传的图片

操作演示:

参考资料

做了一个图床网站 sm.ms - V2EX

GitHub - jokin1999/SMMS_Uploader: SMMS 图床批量上传工具带GUI图形界面