关于本地markdown文档发布到各个平台时图片上传很麻烦这档事

最近比较喜欢写一些杂七杂八的东西，然后再把自己写的东西上传到各个平台真的很有成就感。但是因为我是在本地用 markdown 写的，在上传的时候就有点麻烦。

比如在 b 站上传时，在 typora 复制全文粘贴到 b 站的编辑器，文章中的图片就不会复制到其中，这就需要手动上传…… 图片少点还好，但是多的话真的累死人。

硬着头皮上传的多了以后，慢慢发现可以直接复制图片文件后粘贴在相应位置。虽然方便了一点，但还要在文档中找准位置，并在文件夹中找到相应的图片，时间一长眼都花了…… 能不能再方便一点呢？

哦，大概想到办法了：用 python 脚本循环检测剪贴板，在上传的 markdown 文档中复制图片链接后，python 就获取到了图片链接，然后再根据链接复制图片文件到剪贴版，并进行粘贴。

这样只要在 markdown 文档中复制图片链接，就会自动上传图片了。好棒！

好长时间不弄真的忘了好多，花了一天多终于写出来了，大概就是这样（完整源码放在最后）

Copy
def main(relPath=False, autoPaste=True, interval=0.2):
"""
循环检测剪贴板，解析剪贴板内容，根据内容复制图片，可选自动粘贴

:relPath: 相对路径的根路径。
一般markdown中图片使用相对路径，此参数填入md文件所在目录的路径；
如果使用绝对路径，此参数填入False
:autoPaste: 自动粘贴。填True会在复制md图片链接后自动粘贴图片；填False禁用
:interval: 循环检测剪贴板间隔时间（秒）
"""
# 清空剪贴板
pyperclip.copy('')
while True:
time.sleep(interval) # 延时循环

# 读取剪贴板
mdStr = read_clip()

# 解析markdown图片链接，错误返回false
imgPath = md_to_path(mdStr, relPath)

# 打印信息
print_info(mdStr, imgPath)

# 如果解析错误则重启循环
if not imgPath:
continue

# 复制图片至剪贴板
copy_img(imgPath)

# 如果autoPaste（自动粘贴）为Ture则粘贴
if autoPaste:
auto_paste()

if __name__ == '__main__':

# md文件所在目录的路径
relPath = r'X:\your\markdown\dir'

main(relPath)

马上试试吧！

不过发现了一点问题：从 typora 复制全文粘贴到 b 站的编辑器时，不仅图片不会复制到其中，连图片的链接都不会被复制。这可完了，一百多行要白写了吗？

本着不能前功尽弃的态度，又摸索了一会。大概发现了复制不到图片链接的原因，因为在 typora 中图片链接的文本被解析为了图片，所以就复制不到文本（恼，图片和文本都没法复制）。

既然这样的话，那就把图片链接破坏一下，让它不被解析为图片而只是文本。

嘻嘻，快捷键 ctrl+h 替换一下就好啦

很容易就能看到和上边不一样啦，再试了一下果然没有问题了！(还更显眼了真好)

试着上传了一下，啊好棒。鼠标连击三下选中整行，然后 ctrl+c ，那长长的链接就自动变成了图片。sugoi！

本文写到这里，本想就这样结束，但是稍微多想了一点：动图也能上传吗？

比较怀疑，因为在写 copy_img 函数用来复制图片至剪贴板时，借鉴的一篇文章中是将图片转换为位图 “BMP” 然后写入剪贴板。位图可不是动图啊。

参考：python 复制图片到剪贴板 https://www.cnblogs.com/JYB2021/p/14696503.html

试了试，果然不动了。。。这可不行，不然上边的虹夏可都不会动了！！

又看了用另一种方法的另一篇文章并试了一下，这回可以了，感谢 TA！！！

Python3 复制 PNG 透明图片到剪贴板 https://blog.csdn.net/MowChan/article/details/122823017

好了，真好用，现在就去上传啦！

Copy
# coding: utf-8

import time
import re
import os

# pip install pyperclip, 简单调用剪贴板
import pyperclip

# pip install pywin32, win32clipboard是操作剪贴板的模块
import win32clipboard as clp

# pip install pyautogui, 自动化
import pyautogui

def read_clip():
"""
**读取剪贴板**

"""
return pyperclip.paste()

def md_to_path(mdStr, relPath=False):
"""
**解析markdown图片链接**
1. 正则表达式匹配图片路径，如果未匹配到则返回false
2. 如果relPath = False（非相对路径）则不补完路径，
relPath填入目录路径，则据此补全
3. 判断路径文件是否存在，存在返回路径，否则返回false

:mdStr: markdown图片链接，如![...](...)
:relPath: 相对路径根路径。默认为false。
"""

# 1. 匹配路径
# searchObj = re.search(r'^.?!\[.*\]\((.*)\)', mdStr)
searchObj = re.search(r'^.?!.*\((.*)\)', mdStr) # 开头.?防止复制到上一行的换行符？
if not searchObj:
return False
imgPath = searchObj.group(1)

# 2. 补完路径
if relPath:
# 拼接路径并标准化路径名
imgPath = os.path.normpath(
os.path.join(relPath, imgPath))

# 3. 判断路径
if os.path.isfile(imgPath):
return imgPath
else:
return False

def copy_img(file):
"""
**复制图片至剪贴板**
:file: 图片的路径
"""

clp.OpenClipboard()
clp.EmptyClipboard()
wide_path = os.path.abspath(file).encode('utf-16-le') + b'\0'
clp.SetClipboardData(clp.RegisterClipboardFormat('FileNameW'), wide_path)
clp.CloseClipboard()

def auto_paste():
"""
**自动粘贴**
"""
time.sleep(0.5) # 等待0.5秒等待按键抬起防止未知故障
pyautogui.hotkey('ctrl', 'v')

lastStr = ''

def print_info(mdStr, imgPath):
"""
**打印捕获信息**
重复信息或空白不打印
控制打印字数
"""
# 转为字符串防止len报错，并去掉换行打印美观
mdStr = str(mdStr).replace("\n", " ").replace("\r", "")
imgPath = str(imgPath).replace("\n", " ").replace("\r", "")

global lastStr
if mdStr == lastStr:
return False
elif mdStr == '':
return False
lastStr = mdStr

if len((mdStr)) > 100:
print(mdStr[:100]+'...')
else:
print(mdStr)

if len(imgPath) > 100:
print(imgPath[:100]+'...')
else:
print(imgPath)
print('')

return True

def main(relPath=False, autoPaste=True, interval=0.2):
"""
循环检测剪贴板，解析剪贴板内容，根据内容复制图片，可选自动粘贴

:relPath: 相对路径的根路径。
一般markdown中图片使用相对路径，此参数填入md文件所在目录的路径；
如果使用绝对路径，此参数填入False
:autoPaste: 自动粘贴。填True会在复制md图片链接后自动粘贴图片；填False禁用
:interval: 循环检测剪贴板间隔时间（秒）
"""
# 清空剪贴板
pyperclip.copy('')
while True:
time.sleep(interval) # 延时循环

# 读取剪贴板
mdStr = read_clip()

# 解析markdown图片链接，错误返回false
imgPath = md_to_path(mdStr, relPath)

# 打印信息
print_info(mdStr, imgPath)

# 如果解析错误则重启循环
if not imgPath:
continue

# 复制图片至剪贴板
copy_img(imgPath)

# 如果autoPaste（自动粘贴）为Ture则粘贴
if autoPaste:
auto_paste()

if __name__ == '__main__':

# md文件所在目录的路径
relPath = r'X:\your\markdown\dir'

main(relPath)