前言

因为我的阿里云学生机快到期了,所以思来想去决定还是把博客迁移到静态博客,不折腾Typecho了。不过,使用静态博客有个比较麻烦的事就是图片上传。众所周知,在Markdown里插入图片就需要图片链接,以前折腾了各种对象存储,现在觉得用GitHub做图床就挺不错的,速度其实还是挺快的,还有jsDelivr的CDN加速。

步骤

尽管有很多图床工具可以方便地进行图片上传,例如PicGo、uPic等。不过,我觉得对于这个简单的事情,没必要这么麻烦,用Shell脚本就行。于是乎,就简单用Shell脚本做了个GitHub图床工具。其实图床工具要做的事比较简单,主要流程如下:

图床流程

首先是获取图片文件,我们可以指定本地图片文件的路径,不过我还希望能直接从剪贴板获取图片,因为我在博客里使用的图片大部分时候是截图,如果能从剪贴板获取图片的话会比较方便。在Linux上可以用xclip,在MacOS上我也找到了个能将剪贴板上的图片保存为文件的命令行工具:pngpaste,安装:

1
$ brew install pngpaste

然后就是图片压缩了,有的图床工具可能没有图片压缩功能,即使有,压缩效果也可能不够理想。我之前找到两个图片压缩命令行工具:pngquantjpegoptim,分别用于压缩png格式和jpg格式。

然后就是重点“图片上传”了。它其实包含两步,一是给图片换个名字以免重复,这一步其实是很个性化的,每个人可能有各自偏爱的图片命名方式。一般情况下,图床工具会提供一些重命名方式,但一般选择很有限,要做到个性化其实很难的。不过,如果是Shell脚本,就完全可以自己修改代码去自定义了。至于上传到GitHub,这个其实很简单,就一个curl命令就行。

最后,就是输出Markdown格式的图片链接了,至于复制链接到剪贴板,MacOS可以用自带的pbcopy,Linux可以依然用xclip

准备

首先,需要到Personal Access Tokens新建一个token:

ScreenShot-2020-12-05T17:29:50

然后,需要新建一个仓库用于存储图片。

代码

 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
#!/usr/bin/env bash
GITHUB_API_TOKEN=your_token
GITHUB_USER_NAME=jlice
GITHUB_USER_EMAIL=i@jlice.top
GITHUB_REPO=blog-assets

function get_file() {
    if [[ -z "$1" ]]; then
        filename="/tmp/ScreenShot-"$(date '+%Y-%m-%dT%H:%M:%S')".png"
        if type pngpaste &> /dev/null; then
            pngpaste "$filename"
        elif type xclip &> /dev/null; then
            xclip -selection clipboard -t image/png -o > "$filename"
        fi
    else
        filename="$1"
    fi
    echo "$filename"
}

function compress() {
    filename="$1"
    suffix=${filename##*.}
    suffix_lower=$(echo $suffix | tr 'A-Z' 'a-z')
    if [[ $suffix_lower == "png" ]]; then
        pngquant --skip-if-larger --ext "."$suffix --force --quality=60-90 "$1"
    elif [[ $suffix_lower == "jpg" || $suffix_lower == "jpeg" ]]; then
        jpegoptim --max=90 --preserve --all-progressive "$1"
    fi
}

function new_filename() {
    filename=$1
    suffix=${filename##*.}
    echo $(date '+%Y/%s')"."$suffix
}

function upload() {
    curl -siL -w "%{http_code}\n" -o /dev/null -X PUT 'https://api.github.com/repos/'$GITHUB_USER_NAME'/'$GITHUB_REPO'/contents/'"$2" \
        -H 'Authorization: token '$GITHUB_API_TOKEN \
        -H 'Content-Type: application/json' \
        --data-raw '{
            "message": "upload",
            "committer": {
                "name": "'$GITHUB_USER_NAME'",
                "email": "'$GITHUB_USER_EMAIL'"
            },
            "content": "'$(base64 "$1")'"
        }'
}

function markdown() {
    alt=$(basename "$1")
    alt=${alt%%.*}
    url="https://cdn.jsdelivr.net/gh/$GITHUB_USER_NAME/$GITHUB_REPO/""$2"
    markdown="![$alt]($url)"
    echo $markdown
    if type pbcopy &> /dev/null; then
        echo $markdown | pbcopy
    elif type xclip &> /dev/null; then
        echo $markdown | xclip -selection clipboard
    fi
}

function main() {
    filename=$(get_file "$1")
    if [[ -f "$filename" ]]; then
        compress "$filename"
        new_file=$(new_filename "$filename")
        upload "$filename" "$new_file"
        markdown "$filename" "$new_file"
    else
        echo "file not found: $filename"
    fi
}

main "$1"

使用方法

编辑最上面的GITHUB_API_TOKEN、GITHUB_USER_NAME等参数,换成你自己的。假设保存为uppic,给它添加x权限即可运行。使用非常简单:

1
2
3
4
# 上传剪贴板图片
$ ./uppic
# 上传本地图片
$ ./uppic "/Users/wjmr/Desktop/test.png"

参考链接