解决Markdown图片问题

里程碑

断断续续一年多,自己搭建的博客遇到的各种问题基本得到解决。

现在整理一下解决问题的思路:

博客用到的东西:Github(托管静态网页)、Hugo、Sublime、Markdown、MathJax、免费图床(gitee)、留言(需要*)

遇到的问题主要有:

图床问题:

使用免费图床是个大问题:目前的解决方案是将图片上床到gitee上,这样国内访问图片速度较快。

图片链接插入问题:

之前我写了自动生成链接的脚本,但是结果输出到了文本文件中,对于图片预览实时性的要求就无法满足。

平台不通用问题:

通用性的问题一直没有解决:对于Latex公式的支持,图床的支持

以前由于各个平台不通用的问题,导致我们一直只能在一个平台上写作。而各大平台又各有优缺点,总有令人不满意的地方。

这样下来在本地写的Markdown,不需要做修改可以支持CSDN博客(或者简书)了,直接复制过去就可以。

在未来不久印象笔记windows版本也会支持Markdown,真是个令人振奋的消息。

甚至我还使用过马克飞象,但是它只能配合印象笔记使用,对于跨平台的需求无法满足。

我的github

页面托管到了github上,有兴趣的话可以试着自己搭建一个静态博客。

https://gdhucoder.github.io/

图片本地预览、链接

大家都知道Markdown使用图片需要插入图片链接。

我们使用python写了个脚本,生成文件的缩略图,自动上传gitee,点击图片缩略图,获取链接到剪切板。

解决Markdown图片问题

接下来我又添加的每次打开Helper时,自动提交git,得到最新的图片

然后点击图片缩略图,图片的git地址(可供外网访问的地址)就被拷贝到了剪切板中,在使用的时候我们直接Ctrl+V就可以复制地址到Markdown文档中。

解决Markdown图片问题

这个脚本还支持子目录的打开预览。

因为如果我们只用一个文件夹管理所有的博客图片势必会没有层级结构,导致最后图片混乱。

我们可以建立子文件夹,存放各个主题的图片文件。

解决Markdown图片问题

Picture Helper使用方法:

  1. upload your pictures to github or gitee
  2. this script can generate latest 100 picture links
  3. click the thumb picture, then the link is clipped into you clipboard
  4. then use Ctrl+V in your own Markdown
  5. Enjoy!

另附代码

主要参考了PP4E的pyphoto的代码。

各位改改可以用到的地方:
1、自动提交git脚本
2、生成缩略图(PIL的使用)

"""
############################################################################
Introduction:

please upload your local picture folder as a repo in github or gitee(China).
then we can use the image link in our own markdown file
It's really helpful when you regularly write a blog use Markdown.

1. upload your pictures to github or gitee
2. this script can generate latest 100 picture links
3. click the thumb picture, then the link is clipped into you clipboard
4. then use Ctrl+V in your own Markdown
5. Enjoy!

Modify from PP4E: PyPhoto 1.1: thumbnail image viewer with resizing and saves.
Features:
1. support subdir in your local git folder
2. Please modify some constance in the script

huguodong
gdong.hu[at]gmail
2018-10-19
############################################################################
"""


import sys, math, os
from tkinter import *
from tkinter.filedialog import SaveAs, Directory

from PIL import Image                         # PIL Image: also in tkinter
from PIL.ImageTk import PhotoImage            # PIL photo widget replacement

# remember last dirs across all windows
saveDialog = SaveAs(title='Save As (filename gives image type)')
openDialog = Directory(title='Select Image Directory To Open')
git_master = "https://gitee.com/gdhu/prvpic/raw/master/"
local_git_root_folder = 'E:/gitpic/'
thumb_dir='thumbs'

trace = print  # or lambda *x: None
appname = 'MarkDown Picture Helper: '

class ScrolledCanvas(Canvas):
    """
    a canvas in a container that automatically makes
    vertical and horizontal scroll bars for itself
    """
    def __init__(self, container):
        Canvas.__init__(self, container)
        self.config(borderwidth=0)
        vbar = Scrollbar(container)
        hbar = Scrollbar(container, orient='horizontal')

        vbar.pack(side=RIGHT,  fill=Y)                 # pack canvas after bars
        hbar.pack(side=BOTTOM, fill=X)                 # so clipped first
        self.pack(side=TOP, fill=BOTH, expand=YES)

        vbar.config(command=self.yview)                # call on scroll move
        hbar.config(command=self.xview)
        self.config(yscrollcommand=vbar.set)           # call on canvas move
        self.config(xscrollcommand=hbar.set)


def onDirectoryOpen(event):
    """
    open a new image directory in new pop up
    available in both thumb and img windows
    """
    dirname = openDialog.show()
    if dirname:
        if dirname != local_git_root_folder:
            link = dirname
            link = link.replace(local_git_root_folder, '')
            link = link.replace(thumb_dir,'')
            master = git_master+link
            print(git_master+link)
            viewThumbs(dirname, kind=Toplevel,numcols=5, git=master)
        else:
            viewThumbs(dirname, kind=Toplevel, numcols=5, git=git_master)


def viewThumbs(imgdir, kind=Toplevel, numcols=None, height=400, width=500, git=None):
    """
    make main or pop-up thumbnail buttons window;
    uses fixed-size buttons, scrollable canvas;
    sets scrollable (full) size, and places
    thumbs at abs x,y coordinates in canvas;
    no longer assumes all thumbs are same size:
    gets max of all (x,y), some may be smaller;
    """
    win = kind()
    helptxt = '(press D to open other)'
    win.title(appname + imgdir + '  ' + helptxt)
    quit = Button(win, text='Quit', command=win.quit, bg='beige')
    quit.pack(side=BOTTOM, fill=X)
    linkLabel = Label(win, text='click thumb to copy gitlink to clipboard')
    linkLabel.pack(side=BOTTOM, fill=X)
    canvas = ScrolledCanvas(win)
    canvas.config(height=height, width=width)       # init viewable window size
                                                    # changes if user resizes
    thumbs = makeThumbs(imgdir)                     # [(imgfile, imgobj)]
    numthumbs = len(thumbs)
    if not numcols:
        numcols = int(math.ceil(math.sqrt(numthumbs)))  # fixed or N x N
    numrows = int(math.ceil(numthumbs / numcols))       # 3.x true div

    # max w|h: thumb=(name, obj), thumb.size=(width, height)
    linksize = max(max(thumb[1].size) for thumb in thumbs)
    trace(linksize)
    fullsize = (0, 0,                                   # upper left  X,Y
        (linksize * numcols), (linksize * numrows) )    # lower right X,Y
    canvas.config(scrollregion=fullsize)                # scrollable area size

    rowpos = 0
    savephotos = []
    if not git:
        git = git_master
    while thumbs:
        thumbsrow, thumbs = thumbs[:numcols], thumbs[numcols:]
        colpos = 0
        for (imgfile, imgobj) in thumbsrow:
            photo   = PhotoImage(imgobj)
            link    = Button(canvas, image=photo)
            text = Text()
            def handler(f=imgfile, txt=text,label=linkLabel):
                imglink = "![" + f.split('.')[0] + "](" + git + f + ")";
                txt.clipboard_clear()
                txt.clipboard_append(imglink)
                label.config(text=imglink)
                print(imglink)
            link.config(command=handler, width=linksize, height=linksize)
            link.pack(side=LEFT, expand=YES)
            canvas.create_window(colpos, rowpos, anchor=NW,
                    window=link, width=linksize, height=linksize)
            colpos += linksize
            savephotos.append(photo)
        rowpos += linksize
    win.bind('<KeyPress-d>', onDirectoryOpen)
    win.savephotos = savephotos
    return win

def makeThumbs(imgdir, size=(100, 100), subdir='thumbs', latest=None):
    """
    get thumbnail images for all images in a directory; for each image, create
    and save a new thumb, or load and return an existing thumb;  makes thumb
    dir if needed;  returns a list of (image filename, thumb image object);
    caller can also run listdir on thumb dir to load;  on bad file types may
    raise IOError, or other;  caveat: could also check file timestamps;
    """
    thumbdir = os.path.join(imgdir, subdir)
    if not os.path.exists(thumbdir):
        os.mkdir(thumbdir)

    thumbs = []
    file_list = os.listdir(imgdir)
    file_list.sort(key=lambda x: os.stat(imgdir + "/" + x).st_mtime, reverse=True)
    if not latest:
        limit_num = 50
    for imgfile in file_list[:limit_num]:
        print(imgfile)
        thumbpath = os.path.join(thumbdir, imgfile)
        if os.path.exists(thumbpath):
            thumbobj = Image.open(thumbpath)            # use already created
            thumbs.append((imgfile, thumbobj))
        else:
            print('making', thumbpath)
            imgpath = os.path.join(imgdir, imgfile)
            try:
                imgobj = Image.open(imgpath)            # make new thumb
                imgobj.thumbnail(size, Image.ANTIALIAS) # best downsize filter
                imgobj.save(thumbpath)                  # type via ext or passed
                thumbs.append((imgfile, imgobj))
            except:                                     # not always IOError
                print("Skipping: ", imgpath)
    return thumbs

def commitToGit():

    # 执行提交代码到git操作
    cmd = 'E:&cd E:\gitpic&git add --all&git commit -m "update"&git push -f origin master'
    # cmd = 'ipconfig'
    result = os.popen(cmd)
    print(result.read())



if __name__ == '__main__':

    commitToGit()

    """
    open dir = default or cmdline arg
    else show simple window to select
    """
    imgdir = 'E:\gitpic'
    if len(sys.argv) > 1:
        imgdir = sys.argv[1]
    if os.path.exists(imgdir):
        mainwin = viewThumbs(imgdir, kind=Tk,numcols=5)
    else:
        mainwin = Tk()
        mainwin.title(appname + 'Open')
        handler = lambda: onDirectoryOpen(None)
        Button(mainwin, text='Open Image Directory', command=handler).pack()
    mainwin.mainloop()