使用Typora编辑markdown上传CSDN时图片大小调整麻烦问题

本文档介绍了一个使用Python正则表达式处理Markdown文件的脚本,旨在解决Typora中缩放图片在CSDN上无法正确显示的问题。脚本通过替换图片URL并调整图片大小,确保在CSDN上图片能够居中且尺寸适中。同时,脚本还提供了添加水印和处理不同缩放比例图片的功能。通过将.md文件放入指定目录,运行脚本后,将新生成的文件上传到CSDN即可实现图片的适配。
摘要由CSDN通过智能技术生成

一、问题来源

我日常写博客时,首先使用 typora 编辑 markdown 文件,然后在 CSDN 的 markdown 编辑器中导入 .md 文件。但是使用 typora 的小伙伴们都知道,typora 中缩放图片时使用的是 zoom 属性,然而 CSDN 并不支持这个属性。因此在导入用 typora 写好的 .md 文件时,在 CSDN 上观看时图片老大一个,并且不会自动居中,因此十分不爽。

typora中不改变图片大小后直接粘贴的效果:
image-20220629162157125

二、解决方案

这里使用 python 正则匹配来替换所有图片对应的 url 内容。经过测试,只需要将 .md 文件放入项目工程中,运行 python 脚本后,把新生成的 .md 文件拷贝到 CSDN 中即可。下面介绍具体方案:

(一)创建工程项目

使用 pycharm 创建工程项目,在项目文件夹下创建两个文件夹 in 和 out。in 文件夹存储待处理的 .md 文件,out 文件夹为输出文件夹:
在这里插入图片描述
当然,如果你使用的是 vscode 或者其他 idle,类似即可,配置不复杂。

(二)代码

编写代码,这里我把我自己写的代码附上,仅供参考:

import re

file_name = "Unity核心8——模型导入.md"  # 需要转换的文件名
default_scale = 50  # 图片默认的缩放百分比
zoom_scale = 0.5  # 整体调整原来 typora 中的 zoom 属性大小


# 水印相关参数
watermark = "x-oss-process=image/watermark"  # 为图片添加图片或文字水印
type = "ZHJvaWRzYW5zZmFsbGJhY2s"  # 文字水印字体(Base64编码)
shadow = "50"  # 指定文字水印的阴影透明度
text = "Q1NETiBAemhlbGlrdQ=="  # 文字水印内容(Base64编码)
size = "20"  # 文字水印大小
color = "FFFFFF"  # 文字水印颜色
t = "70"  # 水印图片或水印文字的透明度
g = "se"  # 水印位置

if_watermark = True  # 是否为图片添加水印


def generate_watermark():  # 根据上述参数生成水印
    return f"?{watermark},type_{type},shadow_{shadow},text_{text},size_{size},color_{color},t_{t},g_{g}"


def alter(s):  # 处理未修改大小的图片
    return '<img src="' + s.group(2) + (
        generate_watermark() if if_watermark else "") + f'#pic_center" width="{default_scale}%">'


def alter_zoom(s):  # 处理 typora 中用 zoom 属性修改过大小的图片
    scale = zoom_scale * int(s.group(3))
    return s.group(1) + (generate_watermark() if if_watermark else "") + "#pic_center" + s.group(
        2) + f'width="{scale}%"' + s.group(4)


with open("./in/" + file_name, "r", encoding="utf-8") as fin, open("./out/" + file_name, "w", encoding="utf-8") as fout:
    pattern = re.compile(r"(!\[image-\d+]\()(.+)(\))")  # 未修改大小的图片的匹配规则
    pattern_zoom = re.compile(r'(<img src=".*)(" .* )style="zoom:\s?(\d+)%;"(\s?/>)')  # 带有 zoom 属性的图片的匹配规则
    content = fin.read()  # 读取文件内容
    content1 = pattern.subn(alter, content)  # 第一次处理
    content2 = pattern_zoom.subn(alter_zoom, content1[0])  # 第二次处理
    fout.write(content2[0])  # 写入新文件
    print("原始图片替换次数:", content1[1])
    print("zoom 属性图片替换次数:", content2[1])
    print("总共替换次数:", content1[1] + content2[1])

关于水印参数部分,不清楚的可以参考 这篇文章

这里我将图片分为两种,一种是直接复制进 typora 的,即 ![…](…) 这种类型的链接图片。另一种是在 typora 中右键修改过大小的带有 zoom 属性的链接图片。

  • 对于第一种图片,替换后默认缩放大小为 default_scale%;
  • 对于第二种,原本是想保留原来的 zoom 属性值,直接替换为 width 属性。后来想想还是设置了一个缩放比例 zoom_scale。即,原来图片大小为 zoom: 50% 的图片,经过处理后变为 width: 50 * zoom_scale%

当然这里我的图片链接并不是本地的,我设置了云图床。如果你的图片链接是本地链接(即,使用了 assets 文件夹),那么复制到 CSDN 时可能转换失败。我这里没尝试过本地链接,在这里附上 typora 图床的配置教程

配置完成后,将 .md 文件放入 in 文件夹,修改 file_name,运行脚本后,直接把 out 文件夹中新生成的 .md 文件复制到 CSDN 的 markdown 编辑器即可。对应的图片大小自己微调就好。也可以自己修改代码调整参数自行配置~


2022-06-30 更新

今天上传时,发现并不能直接用 zoom 属性替换 width 的百分比属性,两个属性还是不一样的。因此在原来的代码基础上添加了获取图片大小的功能,将图片大小设置为固定值,该值为 原图大小 * zoom 属性值:

import io
import re
import urllib.request
from PIL import Image

file_name = "Unity核心8——模型导入.md"  # 需要转换的文件名
scale = 0.6  # 图片整体缩放比例

# 水印相关参数
watermark = "x-oss-process=image/watermark"  # 为图片添加图片或文字水印
type = "ZHJvaWRzYW5zZmFsbGJhY2s"  # 文字水印字体(Base64编码)
shadow = "50"  # 指定文字水印的阴影透明度
text = "Q1NETiBAemhlbGlrdQ=="  # 文字水印内容(Base64编码)
size = "20"  # 文字水印大小
color = "FFFFFF"  # 文字水印颜色
t = "70"  # 水印图片或水印文字的透明度
g = "se"  # 水印位置

if_watermark = True  # 是否为图片添加水印


def generate_watermark():  # 根据上述参数生成水印
    return f"?{watermark},type_{type},shadow_{shadow},text_{text},size_{size},color_{color},t_{t},g_{g}"


def get_size(img_path):  # 根据图片链接获取图片的大小
    response = urllib.request.urlopen(img_path)
    temp_img = io.BytesIO(response.read())
    img = Image.open(temp_img)
    return img.size


def alter(s):  # 处理未修改大小的图片
    w, h = get_size(s.group(2))
    new_w, new_h = int(scale * w), int(scale * h)
    return '<img src="' + s.group(2) + (
        generate_watermark() if if_watermark else "") + f'#pic_center" width="{new_w}" height="{new_h}">'


def alter_zoom(s):  # 处理 typora 中用 zoom 属性修改过大小的图片
    zoom_value = int(s.group(4)) / 100
    w, h = get_size(s.group(2))
    new_w, new_h = int(zoom_value * w), int(zoom_value * h)
    return s.group(1) + s.group(2) + (generate_watermark() if if_watermark else "") + "#pic_center" + s.group(
        3) + f'width="{new_w}" height="{new_h}"' + s.group(5)


with open("./in/" + file_name, "r", encoding="utf-8") as fin, open("./out/" + file_name, "w", encoding="utf-8") as fout:
    pattern = re.compile(r"(!\[image-\d+]\()(.+)(\))")  # 未修改大小的图片的匹配规则
    pattern_zoom = re.compile(r'(<img src=")(.*)(" .* )style="zoom:\s?(\d+)%;"(\s?/>)')  # 带有 zoom 属性的图片的匹配规则
    content = fin.read()  # 读取文件内容
    content1 = pattern.subn(alter, content)  # 第一次处理
    content2 = pattern_zoom.subn(alter_zoom, content1[0])  # 第二次处理
    fout.write(content2[0])  # 写入新文件
    print("原始图片替换次数:", content1[1])
    print("zoom 属性图片替换次数:", content2[1])
    print("总共替换次数:", content1[1] + content2[1])

2024-01-13 更新

这次又改进了一下代码,现在可以根据 typora 中图片的大小来进行缩放后,上传到 CSDN。

  1. alter 函数中,width = int(w * scale / max_width * 100)
    typora 中的原始图片宽度为 w,我们默认宽度 max_width = 960 为标准宽度,即对应的 width=100%。因此计算后,可依据 scale 缩放因子来调节 CSDN 中的 width 大小。
  2. alter_zoom 函数中,width = int(w * scale * zoom_value / max_width * 100)
    typora 中的原始图片宽度为 w * zoom_value,即多乘了一个 typora 中的 zoom 属性。后续计算一样。

用的时候可以更改 scale 的值来调整你想要的全局缩放大小。

import io
import re
import urllib.request

from PIL import Image

file_dir = "./in"  # 需要转换的文件夹
scale = 1.2  # 图片整体缩放比例
use_width_percent = True  # 是否使用 width 百分比属性放缩
max_width = 960  # 标准图片宽度参考值

# 水印相关参数
watermark = "x-oss-process=image/watermark"  # 为图片添加图片或文字水印
type = "ZHJvaWRzYW5zZmFsbGJhY2s"  # 文字水印字体(Base64编码)
shadow = "50"  # 指定文字水印的阴影透明度
text = "Q1NETiBAemhlbGlrdQ=="  # 文字水印内容(Base64编码)
size = "20"  # 文字水印大小
color = "FFFFFF"  # 文字水印颜色
t = "70"  # 水印图片或水印文字的透明度
g = "se"  # 水印位置

if_watermark = False  # 是否为图片添加水印


def generate_watermark():  # 根据上述参数生成水印
    return f"?{watermark},type_{type},shadow_{shadow},text_{text},size_{size},color_{color},t_{t},g_{g}"


def get_size(img_path):  # 根据图片链接获取图片的大小
    response = urllib.request.urlopen(img_path)
    temp_img = io.BytesIO(response.read())
    img = Image.open(temp_img)
    # print(img.size)
    return img.size


def alter(s):  # 处理未修改大小的图片
    w, h = get_size(s.group(2))
    new_w, new_h = int(scale * w), int(scale * h)
    width = int(w * scale / max_width * 100)
    if use_width_percent:
        return '<img src="' + s.group(2) + (
            generate_watermark() if if_watermark else "") + f'#pic_center" width="{width}%">'
    else:
        return '<img src="' + s.group(2) + (
            generate_watermark() if if_watermark else "") + f'#pic_center" width="{new_w}" height="{new_h}">'


def alter_zoom(s):  # 处理 typora 中用 zoom 属性修改过大小的图片
    zoom_value = int(s.group(4)) / 100
    w, h = get_size(s.group(2))
    new_w, new_h = int(zoom_value * w), int(zoom_value * h)
    width = int(w * scale * zoom_value / max_width * 100)
    if use_width_percent:
        return s.group(1) + s.group(2) + (generate_watermark() if if_watermark else "") + "#pic_center" + s.group(
            3) + f'width="{width}%"' + s.group(5)
    else:
        return s.group(1) + s.group(2) + (generate_watermark() if if_watermark else "") + "#pic_center" + s.group(
            3) + f'width="{new_w}" height="{new_h}"' + s.group(5)


file_name = "第24章 预处理指令.md"
with open("./in/" + file_name, "r", encoding="utf-8") as fin, open("./out/" + file_name, "w",
                                                                   encoding="utf-8") as fout:
    pattern = re.compile(r"(!\[image-\d+]\()(.+)(\))")  # 未修改大小的图片的匹配规则
    pattern_zoom = re.compile(r'(<img src=")(.*)(" .* )style="zoom:\s?(\d+)%;"(\s?/>)')  # 带有 zoom 属性的图片的匹配规则
    content = fin.read()  # 读取文件内容
    content1 = pattern.subn(alter, content)  # 第一次处理
    content2 = pattern_zoom.subn(alter_zoom, content1[0])  # 第二次处理
    fout.write(content2[0])  # 写入新文件
    print("原始图片替换次数:", content1[1])
    print("zoom 属性图片替换次数:", content2[1])
    print("总共替换次数:", content1[1] + content2[1])

三、项目工程文件

GitHub 仓库地址:https://github.com/zheliku/CSDN_with_Typora

四、问题遗留

近期使用 python 生成的 .md 直接复制到 CSDN 上传发布后,CSDN 总是会将图片链接中的 #pic_center 删除,导致每次都需要重新在 CSDN 里面手打每一张图片的 #pic_center,这样上传后才能正常居中显示。有解决办法的小伙伴可以评论留言,感激不尽~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔗理苦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值