Markdown 写起来方便、排版好看,深受开发者喜爱。但有一个硬伤:它不支持内嵌图片。所有图片都是通过外部链接引用的,这意味着分享 Markdown 文件时,你必须把图片一起发过去,还要确保对方的文件路径和你完全一致。

图片一多,光维护路径就很麻烦。不过这个问题有解。利用 Base64 编码,可以将图片直接转成文本嵌入 Markdown 文件中,一个文件包含全部内容,分享时不再需要额外携带图片文件。

在截屏快捷键截屏后直接复制base64编码到Markdown编辑器。

import win32ui
import os
import base64
from PIL import Image, ImageGrab

# 临时文件使用当前脚本目录
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
TEMP_FILE = os.path.join(SCRIPT_DIR, "1.png")

def get_image():
# 优先读取剪贴板图片
im = ImageGrab.grabclipboard()

if isinstance(im, Image.Image):
return im

# 剪贴板没有图片,弹出文件选择
dlg = win32ui.CreateFileDialog(1)
dlg.SetOFNInitialDir(os.path.expanduser("~/Pictures"))

if dlg.DoModal() != 1:
return None

filename = dlg.GetPathName()

if not filename:
return None

return Image.open(filename)

def main():

img = get_image()

if img is None:
print("未选择图片")
return

# 转 RGB,避免 PNG/JPEG 模式兼容问题
if img.mode != "RGB":
img = img.convert("RGB")

# 只在图片非常大时缩放
# 保留文字清晰度
max_size = 2048

if max(img.size) > max_size:
img.thumbnail(
(max_size, max_size),
Image.Resampling.LANCZOS
)

# PNG 无损保存
img.save(
TEMP_FILE,
format="PNG",
optimize=True
)

# Base64编码
with open(TEMP_FILE, "rb") as f:
base64_data = base64.b64encode(
f.read()
).decode()

# 输出 Markdown 图片
print(
"![](data:image/png;base64,%s)"
% base64_data
)

# 删除临时文件
os.remove(TEMP_FILE)

if __name__ == "__main__":
main()

然后用VBS脚本将图片复制到剪切板

Set ws = createObject("WScript.shell")
ws.run "cmd /c python -u D:\pathto\base64pic.py | clip", vbhide

这样我们可以先用工具截图,然后当我们剪切板有图片存在的时候,运行这个vbs,就可以将图片转换成base64数据然后直接放到剪切板里面了。

如果脚本路径有中文,保存VBS代码的时候需要使用GBK保存,不然会出问题!!!。


更新:

如果不需要裁剪图片,将base64pic.py替换为下面的代码。

import win32ui
import os
import base64
from PIL import Image, ImageGrab


# 临时文件使用当前脚本目录
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
TEMP_FILE = os.path.join(SCRIPT_DIR, "1.png")


def get_image():
    # 优先读取剪贴板图片
    im = ImageGrab.grabclipboard()

    if isinstance(im, Image.Image):
        return im

    # 剪贴板没有图片,弹出文件选择
    dlg = win32ui.CreateFileDialog(1)
    dlg.SetOFNInitialDir(os.path.expanduser("~/Pictures"))

    if dlg.DoModal() != 1:
        return None

    filename = dlg.GetPathName()

    if not filename:
        return None

    return Image.open(filename)


def main():

    img = get_image()

    if img is None:
        print("未选择图片")
        return


    # 转 RGB,避免 PNG/JPEG 模式兼容问题
    if img.mode != "RGB":
        img = img.convert("RGB")


    # 只在图片非常大时缩放
    # 保留文字清晰度
    max_size = 2048

    if max(img.size) > max_size:
        img.thumbnail(
            (max_size, max_size),
            Image.Resampling.LANCZOS
        )


    # PNG 无损保存
    img.save(
        TEMP_FILE,
        format="PNG",
        optimize=True
    )


    # Base64编码
    with open(TEMP_FILE, "rb") as f:
        base64_data = base64.b64encode(
            f.read()
        ).decode()


    # 输出 Markdown 图片
    print(
        "![](data:image/png;base64,%s)"
        % base64_data
    )


    # 删除临时文件
    os.remove(TEMP_FILE)


if __name__ == "__main__":
    main()

4 Replies to “BASE64图片嵌入MD文件的方法”

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注