Vic's blog Vic's blog
首页
  • 前端文章

    • JavaScript
    • Vue
    • HTML
    • CSS
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • TypeScript笔记
    • JS设计模式总结笔记
  • 微服务
  • Database
  • Python
  • 学习笔记

    • Java面试宝典
    • 《一个人工智能的诞生》笔记
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • 学习笔记

    • 《Git》学习笔记
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 大数据
  • 微服务
  • Java面试
关于
  • 网站
  • 资源
  • Vue资源
  • Java面试真题汇总
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Vic xu

永远期待美好的事情将会发生
首页
  • 前端文章

    • JavaScript
    • Vue
    • HTML
    • CSS
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • TypeScript笔记
    • JS设计模式总结笔记
  • 微服务
  • Database
  • Python
  • 学习笔记

    • Java面试宝典
    • 《一个人工智能的诞生》笔记
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • 学习笔记

    • 《Git》学习笔记
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 大数据
  • 微服务
  • Java面试
关于
  • 网站
  • 资源
  • Vue资源
  • Java面试真题汇总
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术文档

  • GitHub技巧

  • 云原生

  • 博客搭建

    • 解决百度无法收录搭建在GitHub上的个人博客的问题
    • 使用Gitalk实现静态博客无后台评论系统
    • GitHub + jsDelivr + TinyPNG+ PicGo 打造稳定快速、高效免费图床
    • 博客源码从GitHub迁移到DevClod
    • 集成云开发 CloudBase Framework 框架「Function」插件
    • 使用Markmap实现在线思维导图
    • Typora+gitee+自定义命令实现图床
      • 背景
      • 思路
      • 实现
        • 创建仓库
        • 实现上传代码
        • 打包输出jar
        • Typora配置上传
    • vdoing主题效果图
  • 学习笔记

  • 技术
  • 博客搭建
xushengli
2021-09-13

Typora+gitee+自定义命令实现图床

# 背景

众所周知,markdown作为一个轻量级标记语言在文档书写方面非常好用,可以说是程序员必备。但是其也存在一定的缺点,比如在文档中插入本地图片后,图片在本地能够正常显示,但将文档分享给其他人图片就不能显示。

针对这个问题,各家markdown书写工具都提供本地图片上传功能,只需要经过简单的配置即可将图片上传到图床,这样再将文档分享出去后,图片链接变为公网链接,其他人就能正常访问。

# 思路

为了解决图片上传的问题,我们需要选择一个可靠方便的图片上传方案。可供选择的有多种方案:代码仓库存储图片(Github、gitee),第三方图传服务(七牛、又拍云)、对象存储OSS(阿里云、腾讯云)、云网盘(百度云)、MetaWeblog(博客园)。

因为一直使用的是Typora ,这个编辑器的确很好用,并且支持整合图像上传服务,所以直接使用Typora 的自定义命令功能实现图片上传功能。

Typora: Typora 向程序输入图片的本地地址,读取文件内容,调用上传的API,然后接收程序的输出,再用其替换文档中的图片。

图床: 直接使用gitee仓库,提供了方便的Gitee Open API (opens new window)支持文件上传,访问高速稳定。

# 实现

# 创建仓库

首先在gitee上新建一个代码仓库,用于保存图片文件。

然后需要创建私人令牌,用于访问Gitee Open API的认证。

image-20210913175735826

保存生成的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;
    }
}

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
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,

  1. 构建请求参数和token

  2. 编码文件内容

  3. 调用https请求接口上传文件

  4. 获取到到下载链接

# 打包输出jar

编写好的java代码使用maven的package命令打包,输出.jar文件。

image-20210913181456533

# Typora配置上传

Typora中配置中配置上传服务

点击,偏好设置-->图像

image-20210913181533921

设置自定义命令

java -jar D:/DevTools/typora-custom-script-1.0-SNAPSHOT-jar-with-dependencies.jar

验证一下,图片上传成功

image-20210913181612523

编辑 (opens new window)
上次更新: 2021/09/17, 14:39:01
使用Markmap实现在线思维导图
vdoing主题效果图

← 使用Markmap实现在线思维导图 vdoing主题效果图→

最近更新
01
万字长文:选 Redis 还是 MQ,终于说明白了!
10-11
02
字节终面:两个文件的公共url怎么找?
09-09
03
ZooKeeper面试题
08-29
更多文章>
Theme by Vdoing | Copyright © 2019-2022 Vic | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×