markdown图片问题的处理

Author : zbzhen,        Modified : Sun Apr 21 09:11:33 2024

1. 基本思路

本地md很容易搞定图片问题, vscode有很多插件可以解决图片问题, 例如 shd101wyy.markdown-preview-enhanced

有很多时候我们并不希望把图上传到图床

但是希望图片能在公众号, 知乎等平台正常显示

推荐先vscode写好本地md, 运行下面的python代码, 生成xxx_base46.md文件

然后粘贴到 https://code.kz16.top/

最后上传到公众号, 知乎等平台

base64代码太长, 影响md体验, 因此准备两个文件可以轻松解决这个问题.
图床安全性真的不高, 而且还要付费, 也需要折腾
如果嫌弃这种方法麻烦, 也可以通过 https://kz16.top/png2base64.html 直接把图片整成base64. 但是那样的话, md文件会变得很大, 也不推荐

公式或者图片特别多建议用火狐浏览器

1.1. 能兼容的语法

参考 这里

2. python代码

2.1. python代码pdf转高清png

from pdf2image import convert_from_path
import matplotlib.pyplot as plt
import os
import glob
def pdf2png(pdf_path):
    images = convert_from_path(pdf_path)
    for i, image in enumerate(images):
        plt.imshow(image)
        plt.axis('off')
        plt.savefig(pdf_path[:-4]+f'_page_{i+1}.png', bbox_inches='tight', pad_inches=0, dpi=800)
        plt.clf()
current_directory = os.getcwd()
pattern = os.path.join(current_directory, '*.pdf')
pdf_files = glob.glob(pattern)
for pdf in pdf_files:
    print(pdf)
    pdf2png(pdf)

2.2. python代码md图片转base64

运行程序后会对把当前文件夹下的所有*.md文件克隆为*_base64.md文件, 并且把图片链接转换为base64编码. python代码如下

在运行下面的脚本之前, 建议先用简单的文档测试.

import re
import requests
import base64
import os


def replace_markdown_image_with_svg(text):
    pattern = r'!\[.*?\]\((<svg.*?<\/svg>)\)'
    replaced_text = re.sub(pattern, r'\1', text)
    return replaced_text

def encode_image(image_path):
    if image_path[:6] == 'https:' or image_path[:5] == 'http:':
        response = requests.get(image_path)
        return base64.b64encode(response.content).decode('utf-8')
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode('utf-8')
    
def svgload(image_path):
    if image_path[:6] == 'https:' or image_path[:5] == 'http:':
        response = requests.get(image_path)
        return response.content.decode('utf-8')
    with open(image_path, "rb") as image_file:
        return image_file.read().decode('utf-8')

def get_image_base64(url):
    if url.lower().endswith('.svg'):
        return  f"{svgload(url)}"
    # Determine the image type based on the URL
    if url.lower().endswith('.png'):
        img_type = 'png'
    elif url.lower().endswith('.gif'):
        img_type = 'gif'
    elif url.lower().endswith('.jpg') or url.lower().endswith('.jpeg'):
        img_type = 'jpeg'
    else :
        print('转换图片链接有要求, 那就是图片链接必须能正常访问到图片, 且图片链接以.png, .jpg, .jpeg, .svg结尾. 请确保图片链接的有效性.')
        print('!!!!!!!!!!!!!!!!!!!Image type not supported!!!!!!!!!!!!!!!!!!!!!!!!!!')
        return 
    return f"data:image/{img_type};base64,{encode_image(url)}"

def convert_images_to_base64(md_content):
    # Regex patterns for finding images
    img_patterns = [
        r'!\[.*?\]\((.*?)\)',                               # Markdown image syntax
        r'<img.*?src="([^"]+)".*?>'                         # HTML img tag
    ]
    
    # Function to replace URL with base64
    def replace_with_base64(match):
        url = match.group(1)
        base64_data = get_image_base64(url)
        return match.group(0).replace(url, base64_data) if base64_data else match.group(0)
    
    # Replace all image URLs with base64 data
    for pattern in img_patterns:
        md_content = re.sub(pattern, replace_with_base64, md_content, flags=re.IGNORECASE)
    md_content = replace_markdown_image_with_svg(md_content)
    return md_content

# Main script
def convert_md_file(file_path):
    # Check if the file name ends with '_base64'
    if file_path.endswith('_base64.md'):
        print(f"{file_path} is already in the desired format.")
        return
    
    # Create a new file name with '_base46' suffix
    base_name = os.path.splitext(file_path)[0]
    new_file_path = f"{base_name}_base64.md"
    
    # Read original Markdown file content
    with open(file_path, 'r', encoding='utf-8') as file:
        md_content = file.read()

    # Convert images to base64
    new_md_content = convert_images_to_base64(md_content)

    # Write the modified content to the new Markdown file 
    with open(new_file_path, 'w', encoding='utf-8') as file:
        file.write(new_md_content)
    
    print(f"Converted file saved as {new_file_path}")
 
for file in os.listdir('.'):
    if file.endswith('.md') and not file.endswith('_base64.md'):
        convert_md_file(file)

3. css样式

需要在这里 https://code.kz16.top/ 修改

3.1. css 小字号主题代码

/*自定义样式,实时生效*/

/* 全局属性
* 页边距 padding:30px;
* 全文字体 font-family:optima-Regular;
* 英文换行 word-break:break-all;
*/
#nice {
  line-height: 1.25;
  font-family: Optima-Regular, Optima, PingFangTC-Light, PingFangSC-light, PingFangTC-light;
  letter-spacing: 2px;
  background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.05) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.05) 3%, rgba(0, 0, 0, 0) 3%);
  background-size: 20px 20px;
  background-position: center center;
}

/* 段落,下方未标注标签参数均同此处
  * 上边距 margin-top:5px;
  * 下边距 margin-bottom:5px;
  * 行高 line-height:26px;
  * 词间距 word-spacing:3px;
  * 字间距 letter-spacing:3px;
  * 对齐 text-align:left;
  * 颜色 color:#3e3e3e;
  * 字体大小 font-size:16px;
  * 首行缩进 text-indent:2em;
  */
#nice p {
  margin: 10px 0px;
  letter-spacing: 2px;
  font-size: 14px;
  word-spacing: 2px;
}

/* 一级标题 */
#nice h1 {
  font-size: 20px;
}


/* 一级标题内容 */
#nice h1 .content {
  display: inline-block;
  font-weight: bold;
	 background-color: #FADFA3; 
	 color: #D14B28;
	 padding: 5px 15px; 
	 border-radius: 20px; 
	 border: 1px solid #9c98ea;
	 display: inline-block; 
	 font-weight: bold; 
	 text-align: center;
	 box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.1); 
}

/* 一级标题修饰 请参考有实例的主题 */
#nice h1:after {}

/* 二级标题 */
#nice h2 {
  text-align: left;
  margin: 20px 10px 0px 0px;
}

/* 二级标题内容 */
#nice h2 .content {
  font-size: 16px;
  font-weight: bold;
  display: inline-block;
  padding-left: 10px;
  border-left: 5px solid #916dd5;
  	 background-color: #AAFFA3; 
	 color: #D14B48;
	 padding: 5px 15px; 
	 border-radius: 20px; 
	 border: 1px solid #9c98ea;
	 display: inline-block; 
	 font-weight: bold; 
	 text-align: center;
	 box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.1); 
}

/* 二级标题修饰 请参考有实例的主题 */
#nice h2:after {}

/* 三级标题 */
#nice h3 {
  font-size: 16px;
  font-weight: bold;
  text-align: left;
}

/* 三级标题内容 */
#nice h3 .content {
  border-bottom: 2px solid #d89cf6;
}

/* 三级标题修饰 请参考有实例的主题 */
#nice h3:after {}

/* 引用
* 左边缘颜色 border-left-color: black;
* 背景色 background: gray;
*/
#nice blockquote {
  border-left-color: #ffb11b;
 background: #fff5e3;
}

/* 引用文字 */
#nice blockquote p {
  color: #595959;
}

/* 链接 */
#nice a {
  border: none;
  text-decoration: none;
  color: #dda52d;
}

#nice a:hover {
  color: #f9bf45;
  text-decoration: underline;
}

/* 无序列表整体样式
 * list-style-type: square|circle|disc;
 */
#nice ul {
}

/* 有序列表整体样式
 * list-style-type: upper-roman|lower-greek|lower-alpha;
 */
#nice ol {
}

/* 列表内容,不要设置li
 */
#nice li section {
}

/* 加粗 */
#nice strong {}

/* 斜体 */
#nice em {}

/* 加粗斜体 */
#nice em strong {}

/* 删除线 */
#nice del {
  color: #d19826;
}

/* 分隔线
* 粗细、样式和颜色
* border-top: 1px solid #3e3e3e;
*/
#nice hr {
  border-top: 1px solid #f9bf45;
  margin: 20px 0px;
}

/* 图片
* 宽度 width: 80%;
* 居中 margin: 0 auto;
* 居左 margin: 0 0;
*/
#nice img {
  width: 100%;
 border-radius: 5px;
 display: block;
 margin-bottom: 15px;
 height: auto;
}

/* 图片描述文字 */
#nice figcaption {
  color: #dda52d;
  font-size: 14px;
}

/* 行内代码 */
#nice p code, #nice li code {
  color: #9b6e23;
  background-color: #fff5e3;
  padding: 3px;
  margin: 3px;
}

/* 非微信代码块
 * 代码块不换行 display: -webkit-box !important;
 * 代码块换行 display: block;
 */
#nice pre code {}

/*
 * 表格内的单元格
 * 字体大小 font-size: 16px;
 * 边框 border: 1px solid #ccc;
 * 内边距 padding: 5px 10px;
 */
#nice table tr th,
#nice table tr td {
  text-align: center;
}

/* 脚注文字 */
#nice .footnote-word {
  color: #ffb11b;
  padding: 3px;
}

/* 脚注上标 */
#nice .footnote-ref {
  color: #dda52d;
  margin: 2px;
  padding: 3px;
}

/* "参考资料"四个字 
 * 内容 content: "参考资料";
 */
#nice .footnotes-sep:before {
  margin: 30px 0px 15px 0px;
  font-weight: 800;
}


/* 参考资料编号 */
#nice .footnote-num {
}

/* 参考资料文字 */
#nice .footnote-item p { 
}

/* 参考资料解释 */
#nice .footnote-item p em {
}

/* 行间公式
 * 最大宽度 max-width: 300% !important;
 */
#nice .block-equation svg {
}

/* 行内公式
 */
#nice .inline-equation svg {  
}

4. mdnice搭建和启动记录

git clone https://github.com/whaoa/markdown-nice.git
npm install
node scripts/start.js test.log