可怜的孩子 不再胆怯
discord server

About the troublesome issue of uploading images when publishing local Markdown documents to various platforms.

Recently, I have been enjoying writing various things and then uploading them to various platforms. It gives me a great sense of accomplishment. However, because I write in Markdown locally, it becomes a bit troublesome when uploading.

For example, when uploading to Bilibili, if I copy the entire text from Typora and paste it into the Bilibili editor, the images in the article will not be copied. I have to manually upload them... It's not a big deal if there are only a few images, but it becomes really tiring if there are many.

After uploading with a bit of effort, I gradually discovered that I can directly copy and paste image files in the corresponding positions. Although it's a bit more convenient, I still have to find the right position in the document and find the corresponding image in the folder. It takes a long time and strains my eyes... Can it be even more convenient?

Oh, I think I have a solution: use a Python script to continuously monitor the clipboard. After copying the image link in the uploaded Markdown document, Python can obtain the image link, and then copy the image file to the clipboard and paste it.

This way, as long as I copy the image link in the Markdown document, the image will be automatically uploaded. How great!

By the way, I realized that when copying the entire text from Typora and pasting it into the Bilibili editor, not only the images are not copied, but even the image links are not copied. This is a problem. Does it mean that I wasted over a hundred lines of code?

With the attitude of not giving up on my previous efforts, I explored a bit more. I found out why the image links were not copied in Typora. It's because the text of the image links is interpreted as images in Typora, so the text cannot be copied (annoying, I can't copy both the image and the text).

Since that's the case, let's modify the image links so that they are not interpreted as images but only as text.

Hehe, just use the shortcut Ctrl+H to replace it.

It's easy to see the difference from the previous one. I tried it and it works perfectly! (It's even more noticeable, which is great)

I tried uploading it, and it's great. Triple-click the mouse to select the entire line, then press Ctrl+C, and the long link will automatically turn into an image. Sugoi!

This is where the article ends. I originally wanted to end it here, but I thought a little more: can animated images be uploaded too?

I was skeptical because when I wrote the copy_img function to copy the image to the clipboard, I referred to an article that converts the image to a bitmap "BMP" and writes it to the clipboard. But a bitmap is not an animated image.

Reference: Copying Images to the Clipboard in Python

I tried it, and it didn't work... This won't do, otherwise the previous images won't be animated!!

I looked at another article that used a different method and tried it. This time it worked, thanks to the author!

Copying PNG Images to the Clipboard in Python 3

Okay, it's really useful. I'm going to upload now!

# coding: utf-8

import time
import re
import os

# pip install pyperclip, a simple module for accessing the clipboard
import pyperclip

# pip install pywin32, a module for manipulating the clipboard
import win32clipboard as clp

# pip install pyautogui, a module for automating GUI interactions
import pyautogui

def read_clip():
    **Read the clipboard**
    return pyperclip.paste()

def md_to_path(mdStr, relPath=False):
    **Parse markdown image links**
    1. Use regular expressions to match the image path. If no match is found, return False.
    2. If relPath = False (absolute path), do not complete the path.
        If relPath is the directory path, complete the path based on it.
    3. Check if the path file exists. If it exists, return the path. Otherwise, return False.

    :mdStr: Markdown image link, e.g. ![...](...)
    :relPath: Root path of relative path. Default is False.

    # 1. Match the path
    # searchObj ='^.?!\[.*\]\((.*)\)', mdStr)
    searchObj ='^.?!.*\((.*)\)', mdStr)  # Use .? at the beginning to prevent copying the newline character from the previous line
    if not searchObj:
        return False
    imgPath =

    # 2. Complete the path
    if relPath:
        # Join the path and normalize the path name
        imgPath = os.path.normpath(
            os.path.join(relPath, imgPath))

    # 3. Check the path
    if os.path.isfile(imgPath):
        return imgPath
        return False

def copy_img(file):
    **Copy the image to the clipboard**
    :file: Path of the image

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

def auto_paste():
    **Automatically paste**
    time.sleep(0.5)  # Wait for 0.5 seconds to prevent unknown malfunctions caused by key release delay
    pyautogui.hotkey('ctrl', 'v')

lastStr = ''

def print_info(mdStr, imgPath):
    **Print captured information**
    Do not print repeated information or blank lines
    Control the number of characters to be printed
    # Convert to string to prevent len error, and remove line breaks for better printing
    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:

    if len(imgPath) > 100:

    return True

def main(relPath=False, autoPaste=True, interval=0.2):
    Continuously monitor the clipboard, parse the clipboard content, copy the image based on the content, and optionally paste automatically.

    :relPath: Root path of relative path.
        Generally, relative paths are used for images in Markdown. Fill in the path of the directory where the md file is located;
        If an absolute path is used, fill in False for this parameter.
    :autoPaste: Auto paste. If set to True, the image will be automatically pasted after copying the md image link; set to False to disable.
    :interval: Interval for monitoring the clipboard (in seconds)
    # Clear the clipboard
    while True:
        time.sleep(interval)  # Delay the loop

        # Read the clipboard
        mdStr = read_clip()

        # Parse the markdown image link, return false if there is an error
        imgPath = md_to_path(mdStr, relPath)

        # Print the information
        print_info(mdStr, imgPath)

        # If there is an error in parsing, restart the loop
        if not imgPath:

        # Copy the image to the clipboard

        # If autoPaste is True, paste automatically
        if autoPaste:

if __name__ == '__main__':

    # Path of the md file directory
    relPath = r'X:\your\markdown\dir'


Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.