Typora 配合 minio 实现图片存储
摘要:本文介绍了 Typora 中的图片,使用 opencv 转换图片格式为 webp,再使用 Python 脚本上传至 Minio 对象存储,以及 Docker 部署 Minio 和 Nginx 反向代理 Minio。
1、环境
服务器 - Ubuntu
- Docker 环境
- Minio
- Nginx
客户端 - Windows
- python 3.x 环境
- typora 软件
2、Minio 部署
(1) 服务器部署 Minio
创建 docker compose 文件。
mkdir -p /root/docker_data/minio/
cd /root/docker_data/minio/
vi compose.yaml
version: '3.8'
services:
minio:
image: minio/minio
hostname: "minio"
ports:
- 9000:9000 # api 端口
- 9001:9001 # 控制台端口
environment:
MINIO_ACCESS_KEY: admin #管理后台用户名
MINIO_SECRET_KEY: Ad1234min_123 #管理后台密码,最小8个字符
volumes:
- /root/docker_data/minio/data:/data #映射当前目录下的data目录至容器内/data目录
- /root/docker_data/minio/config:/root/.minio/ #映射配置目录
command: server --console-address ':9001' /data #指定容器中的目录 /data
privileged: true
restart: always
(2) 配置 nginx 反向代理
需要配置2个反向代理
- 代理1:代理控制台 9001 端口,用于web界面控制
- 代理2:代理 api 9000 端口 ,用于资源访问
# / 匹配默认控制端
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
chunked_transfer_encoding off;
proxy_pass http://127.0.0.1:9001;
}
# 匹配存储桶资源,blog 为存储桶名称
location ^~ /blog {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_ssl_server_name off;
}
# 全部配置文件参考
server {
listen 80 ;
listen 443 ssl http2 ;
server_name oss.yyds.space;
index index.php index.html index.htm default.php default.htm default.html;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
access_log /www/sites/oss.yyds.space/log/access.log main;
error_log /www/sites/oss.yyds.space/log/error.log;
location ^~ /.well-known/acme-challenge {
allow all;
root /usr/share/nginx/html;
}
root /www/sites/oss.yyds.space/index;
if ($scheme = http) {
return 301 https://$host$request_uri;
}
ssl_certificate /www/sites/oss.yyds.space/ssl/fullchain.pem;
ssl_certificate_key /www/sites/oss.yyds.space/ssl/privkey.pem;
ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
error_page 497 https://$host$request_uri;
proxy_set_header X-Forwarded-Proto https;
ssl_stapling on;
ssl_stapling_verify on;
include /www/sites/oss.yyds.space/proxy/*.conf;
}
(3) web 配置 minio
1)访问 minio 控制端
访问 https://oss.yyds.space , 进行控制端登陆,用户名和密码配置在 compose.yaml
中。
2)创建存储桶
创建存储桶,这里创建示例名称为 blog
。
3)修改访问策略
MinIO 默认创建桶的权限是private
私有的,也就是桶内的文件是不允许外界直接访问的,在此更改选项为 public
,就可以实现通过:地址/桶名称/文件名直接访问
4)上传测试图片
上传本地图片 tx.png
,并进行访问测试 https://oss.yyds.space/blog/tx.png,访问成功则,搭建基本完成。
5)获取 Access Key
创建 Access key 并记录到本地,后续脚本需要使用到。
3、Typora 上传图片到 Minio
(1) 配置上传脚本
本文使用 python 脚本进行图片格式转换为webp,并上传到 Minio,Python环境建议使用 3.x,此处不介绍 Python 环境的安装。
1)安装 Python 第三方库
python -m pip config set global.index-url https://mirrors.ustc.edu.cn/pypi/web/simple
python -m pip install minio opencv-python opencv-python-headless numpy
2)配置脚本
在本地创建脚本,示例在 D:\Typora\upload_script\upload.py
配置以下脚本
import sys
import datetime
import cv2
import os
import random
import requests
import io
import numpy as np
from minio import Minio
from pathlib import Path
# 配置以下内容
minio_domain = "oss.yyds.space"
minio_domain_port = "9000"
minio_access_key = "access_key"
minio_secret_key = "secret_key"
# 存储桶名称
bucket_name = "blog"
# 存储桶子文件夹名称
bucket_name_dir_name = "img"
# 获取minio客户端连接
minio_client = Minio(
f"{minio_domain}:{minio_domain_port}",
minio_access_key,
minio_secret_key,
secure=False,
)
# 如果存储桶不存在,则创建
if not minio_client.bucket_exists(bucket_name):
minio_client.make_bucket(bucket_name)
# 判断上传的图片是否为网络图片
def is_url(path_str):
return path_str.lower().startswith("http://") or path_str.lower().startswith(
"https://"
)
# 获取图片参数
images = sys.argv[1:]
# 处理并上传每一张照片
for image_path in images:
# 生成图片文件名,使用年月日时分秒+2位随机数
current_time = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
file_name = "{}{}{}".format(current_time, random.randint(10, 99), ".webp")
# 如果是网络图片则需要下载再进行格式转换,如果是本地图片,则无需下载直接进行格式转换。
if is_url(image_path):
response = requests.get(image_path)
if response.status_code == 200:
img_bytes = io.BytesIO(response.content)
img_array = np.frombuffer(img_bytes.read(), np.uint8)
img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
else:
print(f"Failed to download image from URL: {image_path}")
continue
else:
img = cv2.imread(image_path)
if img is None:
print(f"Unable to read local image file: {image_path}")
continue
# 图片格式转换为WebP
webp_image = cv2.imencode(".webp", img)[1]
# 写入临时WebP文件
temp_image_path = f"{current_time}.webp"
with open(temp_image_path, "wb") as f:
f.write(bytearray(webp_image))
# 文件存储桶下子路径拼接
remote_full_path_name = "{}/{}".format(bucket_name_dir_name, file_name)
# 上传文件
minio_client.fput_object(bucket_name, remote_full_path_name, temp_image_path)
# 删除临时WebP文件
os.remove(temp_image_path)
# 打印文件路径
print("https://{}/{}/{}".format(minio_domain, bucket_name, remote_full_path_name))
(2) 配置 Typora 图片上传
Typora 导航到路径【文件】-> 【偏好设置】-> 【图像】,进行以下设置,上传服务选择 Custom Command
,命令填写 Python 脚本路径
, 点击图片上传选项进行验证
出现验证成功,到此Typora 图片格式转换并上传环境搭建完成,点击 ok 退出。