最近は雑多なものを書くのが好きになってきて、自分が書いたものを各プラットフォームにアップロードするのが本当に達成感があります。しかし、私はローカルで Markdown を使って書いているので、アップロードする際に少し手間がかかります。
例えば、Bilibili にアップロードする際、Typora から全文をコピーして Bilibili のエディタに貼り付けると、記事中の画像がコピーされないため、手動でアップロードする必要があります…… 画像が少なければまだ良いですが、多いと本当に疲れます。
無理やりアップロードを続けているうちに、画像ファイルを直接コピーして適切な位置に貼り付けることができることに気付きました。少し便利になりましたが、文書内で正確な位置を見つけ、フォルダ内で該当する画像を見つける必要があり、時間が経つと目が疲れてしまいます…… もう少し便利にならないでしょうか?
ああ、方法を思いついたかもしれません:Python スクリプトを使ってクリップボードをループで監視し、アップロードする Markdown 文書内で画像リンクをコピーすると、Python が画像リンクを取得し、そのリンクに基づいて画像ファイルをクリップボードにコピーして貼り付けます。
これで Markdown 文書内で画像リンクをコピーするだけで、自動的に画像がアップロードされるようになります。素晴らしい!
長い間やっていなかったので、本当に多くのことを忘れてしまいました。一日以上かかってようやく書き上げました。大体こんな感じです(完全なソースコードは最後に置いておきます)。
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(自動貼り付け)がTrueの場合は貼り付け
if autoPaste:
auto_paste()
if __name__ == '__main__':
# mdファイルがあるディレクトリのパス
relPath = r'X:\your\markdown\dir'
main(relPath)
さあ、試してみましょう!
しかし、少し問題に気付きました:Typora から全文をコピーして Bilibili のエディタに貼り付けると、画像だけでなく画像のリンクもコピーされません。これは困りました、一百行以上を無駄にするのですか?
無駄にしたくないという気持ちで、もう少し探ってみました。おそらく画像リンクがコピーできない理由を発見しました。Typora では画像リンクのテキストが画像として解析されてしまうため、テキストをコピーできないのです(困った、画像とテキストの両方がコピーできません)。
そういうことなら、画像リンクを壊して、画像としてではなくテキストとして解析されるようにしましょう。
えへへ、ショートカットキーの ctrl+h で置き換えれば大丈夫です。
すぐに上のものとは違うことがわかります。もう一度試してみたら、やはり問題ありませんでした!(さらに目立つようになって本当に良かった)
試しにアップロードしてみました、ああ素晴らしい。マウスを三回クリックして行全体を選択し、ctrl+c を押すと、その長いリンクが自動的に画像に変わります。すごい!
この記事はここまでです。このまま終わらせるつもりでしたが、少し考えを巡らせました:アニメーション GIF もアップロードできるのでしょうか?
少し疑問に思いました。なぜなら、copy_img 関数を使って画像をクリップボードにコピーする際に参考にした記事では、画像をビットマップ「BMP」に変換してクリップボードに書き込んでいたからです。ビットマップはアニメーションではありません。
参考:Python で画像をクリップボードにコピーする https://www.cnblogs.com/JYB2021/p/14696503.html
試してみたところ、やはり動きませんでした。。。これは困ります、そうでなければ上の虹夏は動かないままです!!
別の方法を使った別の記事を見て試してみたところ、今回はうまくいきました。感謝します!!!
Python3 で PNG 透明画像をクリップボードにコピーする https://blog.csdn.net/MowChan/article/details/122823017
さて、使いやすくなりました。今すぐアップロードに行きます!
# 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(自動貼り付け)がTrueの場合は貼り付け
if autoPaste:
auto_paste()
if __name__ == '__main__':
# mdファイルがあるディレクトリのパス
relPath = r'X:\your\markdown\dir'
main(relPath)