Typora+gitee+自定义命令实现图床
# 背景
众所周知,markdown作为一个轻量级标记语言在文档书写方面非常好用,可以说是程序员必备。但是其也存在一定的缺点,比如在文档中插入本地图片后,图片在本地能够正常显示,但将文档分享给其他人图片就不能显示。
针对这个问题,各家markdown书写工具都提供本地图片上传功能,只需要经过简单的配置即可将图片上传到图床,这样再将文档分享出去后,图片链接变为公网链接,其他人就能正常访问。
# 思路
为了解决图片上传的问题,我们需要选择一个可靠方便的图片上传方案。可供选择的有多种方案:代码仓库存储图片(Github、gitee),第三方图传服务(七牛、又拍云)、对象存储OSS(阿里云、腾讯云)、云网盘(百度云)、MetaWeblog(博客园)。
因为一直使用的是Typora ,这个编辑器的确很好用,并且支持整合图像上传服务,所以直接使用Typora 的自定义命令功能实现图片上传功能。
Typora: Typora 向程序输入图片的本地地址,读取文件内容,调用上传的API,然后接收程序的输出,再用其替换文档中的图片。
图床: 直接使用gitee仓库,提供了方便的Gitee Open API (opens new window)支持文件上传,访问高速稳定。
# 实现
# 创建仓库
首先在gitee上新建一个代码仓库,用于保存图片文件。
然后需要创建私人令牌,用于访问Gitee Open API的认证。

保存生成的token令牌内容。
# 实现上传代码
代码实现部分,需要调用上传的API,可以使用python,sheel脚本等语言,这里使用java代码完成。
先上代码:
package com.pang;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static com.pang.Config.*;
/**
* @author Pang
* @date 2021/4/22
*/
public class Main {
private static final OkHttpClient CLIENT = new OkHttpClient().newBuilder()
.connectTimeout(5, TimeUnit.SECONDS)
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(Config.PROXY_HOST, 8080)))
.proxyAuthenticator((route, response) -> {
//设置代理服务器账号密码
String credential = Credentials.basic(Config.PROXY_USERNAME, Config.PROXY_PASSWORD);
return response.request().newBuilder().header("Proxy-Authorization", credential).build();
})
.build();
private static final String ACCESS_TOKEN = "access_token";
private static final String CONTENT = "content";
private static final String MESSAGE = "message";
private static final String MESSAGE_VALUE = "上传图片";
private static final String GITEE_BASE_URL = "https://gitee.com";
private static final String GITEE_UPLOAD_URL = GITEE_BASE_URL + "/api/v5/repos/" + GITEE_USER_NAME + "/"
+ GITEE_RESP_NAME + "/contents/";
public static void main(String[] args) throws IOException {
List<String> result = new LinkedList<>();
for (String path : args) {
JSONObject param = new JSONObject();
File file = new File(path);
String fileName = file.getName();
// 读取文件内容
byte[] fileBytes = readFileContent(file);
// 进行base64编码
String encodedFileString = Base64.getEncoder().encodeToString(fileBytes);
// 文件远程路径的url编码
String remoteFilePath = "img/" + System.currentTimeMillis() + "/" + fileName;
// 实际上传url
String realUploadUrl = GITEE_UPLOAD_URL + URLEncoder.encode(remoteFilePath);
// 上传的文件类型
MediaType mediaType = MediaType.parse("application/json;charset=UTF-8");
// 构建参数
param.put(ACCESS_TOKEN, ACCESS_TOKEN_VALUE);
param.put(CONTENT, encodedFileString);
param.put(MESSAGE, MESSAGE_VALUE);
// 构建访问请求
RequestBody body = RequestBody.create(mediaType, param.toJSONString());
// 访问
Request request = new Request.Builder().url(realUploadUrl)
.method("POST", body)
.addHeader("Connection", "keep-alive")
.addHeader("Accept", "application/json, text/plain, */*")
.addHeader("Content-Type", "application/json;charset=UTF-8")
.addHeader("Origin", "https://gitee.com")
.addHeader("Referer", "https://gitee.com/api/v5/swagger")
.addHeader("Accept-Language", "zh,en;q=0.9,zh-CN;q=0.8")
.build();
// 获取访问结果
Response response = CLIENT.newCall(request).execute();
// 将结果转换为json
JSONObject responseJsonObj = JSON.parseObject(response.body().string());
// 获取到下载链接
String downloadPath = responseJsonObj.getJSONObject("content").getString("download_url");
// 添加到结果
result.add(downloadPath);
}
for (String s : result) {
System.out.println(s);
}
}
/**
* 读取文件内容
*
* @param file 文件
* @return 文件内容的编码
*/
public static byte[] readFileContent(File file) {
byte[] fileBytes = new byte[0];
try (FileInputStream fileInputStream = new FileInputStream(file)) {
fileBytes = new byte[(int) file.length()];
fileInputStream.read(fileBytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fileBytes;
}
}
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
主要用到了okhttp3.OkHttpClient,
构建请求参数和token
编码文件内容
调用https请求接口上传文件
获取到到下载链接
# 打包输出jar
编写好的java代码使用maven的package命令打包,输出.jar文件。

# Typora配置上传
Typora中配置中配置上传服务
点击,偏好设置-->图像

设置自定义命令
java -jar D:/DevTools/typora-custom-script-1.0-SNAPSHOT-jar-with-dependencies.jar
验证一下,图片上传成功
