Hexo 引用本地图片以及引用本地任意位置图片的一点思路

前言

之前想在博文里引用本地图片,按着随便搜到的教程无脑折腾了一番,当时记录了下步骤放在博文里,其实根本没搞懂。在 CSDN 上的备份经常被人访问,为了不误人子弟,稍微按自己的理解捋一下。

当然,也不一定正确。

先提一下,我目前的 hexo 版本为 4.0,其它版本可能会有不同。

引用本地图片与插件 hexo-asset-image

引用本地图片

首先要在 Hexo 博客配置添加一行[1]

1
2
# 开始使用本地静态资源
post_asset_folder: true

添加这行配置后,当你什么插件也没安装时,使用 hexo 4.0 也可以在文章引用本地图片,引用方式是这样的:

首先在 _posts 文件夹下建立一个博文文件,比如 2019-12-23-hello-world.md,再建立一个同名的文件夹 2019-12-23-hello-world。这篇文章要引用的图片就放在该文件夹下。

或者 hexo new 2019-12-23-my-post

比如我就在该目录下放一个图片2019-12-23-hello-world/haha.png。然后在博文 Markdown 文件里引用该图片,怎么引用呢?用下面这种方式:

1
![](haha.png)

如果你熟悉 Markdown 语法的话就会注意到,这个引用路径不太对劲。而且通过该路径引用图片,本地的 Markdown 编辑器是不能预览图片的!

本来文章与图片的路径是这样的:

1
2
3
|-- /2019-12-23-hello-world
|---- haha.png
|-- 2019-12-23-hello-world.md

理论上 2019-12-23-hello-world.md 要引用 2019-12-23-hello-world 文件夹下的 haha.png,引用方式应该是:

1
![](2019-12-23-hello-world/haha.png)

这样才对啊!

那么,为什么引用的时候不能加文件夹的路径呢?

这是因为 hexo 在渲染的时候,会把 2019-12-23-hello-world.md 渲染为 public/2019/12/23/hello-world 下的 index.html 网页文件,再把对应文件夹下的静态资源,比如图片 /2019-12-23-hello-world/haha.png 也拷贝到 public/2019/12/23/hello-world 下。

因此,虽然在我们写博文的时候看来,博文和图片不在同一个文件夹路径下,但是它们最终被渲染后,是放在同一个文件夹下的。

像这样:

1
2
3
4
// 渲染后
|-- /public/2019/12/23/hello-world
|---- index.html
|---- haha.png

所以我们在写博文引用图片时,就得把它们当作在一个文件夹下来处理,也就是引用的时候,要去掉文件夹路径。

最后渲染出来的效果是:

1
<img src="haha.png" alt="" />

这样有点反直觉啊!!

或者简单讲,我想在本地编辑器里预览图片,该咋整呢?

关于 hexo-asset-image

根据我看到的情况,hexo-asset-image 插件解决的问题是「给引用的本地图片添加绝对路径。」

毕竟说明里只提到「Give asset image in hexo a absolutely path automatically」……

比如上面渲染出来的图片标签是用的相对路径:

1
<img src="haha.png" alt="" />

经 hexo-asset-image 插件处理后,标签会变成绝对路径:

1
<img src="/2019/12/23/hello-world/haha.png" alt="" />

但是,在我现在的环境(hexo 4.0)发现,使用 hexo-asset-image 插件后,我可以在博文(原 Markdown 文件)里使用

1
![](2019-12-23-hello-world/haha.png)

这种形式来引用图片了!

这样的好处是本地编辑器里也可以直接预览图片。

![](haha.png) 这种方式也仍可正常使用。

跟踪了一下插件的代码,发现插件在获取到 2019-12-23-hello-world/haha.png 这个链接后,会先通过字符串操作获取到后面的 haha.png,然后统一进行「相对路径转绝对路径」的操作。

最后处理为:

1
<img src="/2019/12/23/hello-world/haha.png" alt="" />

有些博文里直接把「解决本地编辑器图片显示」当作 hexo-asset-image 的本来功能,可该插件的 Issue 里还有「如何在本地支持 Markdown 图片显示」……

我觉得可能该插件的本来目的只是「将静态资源的引用路径转化为绝对路径」,至于后面解决了「本地预览」应该是随手做的……不然作者怎么也不说明下……

也可能我理解错了。

老实说我有点迷惑,也许这可能和 Hexo 的历史有关?

安装 hexo-asset-image

不过至今(2019-12-25)为止, hexo 4.0 使用了 npm 仓库里的插件 hexo-asset-image 1.0 有点问题,安装后图片不能正常显示,查看图片路径被渲染成了 /.xx/haha.png 的格式。(xx 是域名后缀。)

但是直接安装 Github 仓库的源码没问题,可以执行:

1
2
npm install https://github.com/xcodebuild/hexo-asset-image.git
# or yarn add https://github.com/xcodebuild/hexo-asset-image.git

具体使用及配置查看 https://github.com/xcodebuild/hexo-asset-image

hexo-asset-image 的说明与问题

我在刚使用 Hexo 时,搜索静态图片的问题,大家都推荐使用 hexo-asset-image 这个插件,也没多做考虑……

现在回头看,其实有许多的轮子可以解决这个问题……比如在 npm 或者 Github 搜索 hexo-assethexo-imge,就能搜到一大堆大佬们的轮子……

甚至能搜到一大堆 hexo-asset-image 的 fix 包……

现在 hexo-asset-image 已经被作者归档了……我想 npm 上的包应该是因为过时没有更新才会出问题的吧……

也许现在应该有更好的解决方案。(但我没研究,毕竟自己的需求够用了……)

使用 hexo-asset-image 可能会遇到一些问题,比如与懒加载插件搭配时的问题。(我遇到了,所以提一下

感觉其它莫名其妙的问题也挺多的……但是这个包现在没人统一维护,有许多人都只能修复了一下自己的问题然后单独说明一下……

hexo-asset-image 与 懒加载的冲突

我在使用 Hexo 的主题 hexo-next-theme 开启图片懒加载时,hexo-asset-image 插件会失效。

跟了下代码,发现 hexo-next-theme 使用的图片懒加载插件是 lozad.js 。这个插件会将 imgsrc 属性改为 data-src。hexo-asset-image 的工作原理是统一处理 src ,没有对 data-src 等属性的判断,所以就不会处理图片。

我自己改了下,想提个 PR 来着,发现原插件仓库已经被归档了……

于是 fork 了一份:hqweay/hexo-asset-image

在解决这个问题的时候,发现也有人遇到过类似的问题。可以参考一下别人的问题:

ci0n/hexo-asset-image

该仓库的 ChangeLog:

2019-09-23: support hexo-lazyload-image
2019-09-23: fixed hexo-abbrlink using *.html image path error

【与正文无关】引用本地任意位置图片的一点思路

hexo 引用本地图片的方式确实不大优雅 —— 必须把图片存储在固定的位置。有时候写一些截图比较多的文章,还得把截图一张张放到那个固定的文件夹,再进行引用。

比较直观的操作应当这样才对:截图后直接粘贴到文档里。

如果用图床,甚至是用 Github 做图床,可以使用 PicGo 这个开源的图床上传工具。它可以把你剪贴板里图片上传到图床,然后返回一个 Markdown 格式的引用路径——再粘贴到你需要的位置即可。

看了一下 hexo-asset-image 的实现方式,想到也许可以把 Markdown 博文中 任意位置的图片 拷贝到相应的文件夹里,然后用类似的方式进行字符串替换。

然后尝试了一下,没做出来……记录一下思路。

首先需要考虑到不同平台的绝对路径不同,我心想先把流程做出来,于是以 Linux 的为准。

然后因为我一开始不懂 hexo 怎么写插件,于是就在 hexo-asset-image 上直接改。我把任意位置图片的路径获取到了,然后就是把该图片往文章对应的文件夹复制了。

这里有两个问题,一是我应该把图片复制到 /public 下还是 /posts 下呢,先复制到 /post 文件夹下吧。

这还有个问题,如果在 /posts 还有子文件夹咋办?管他的,先不管这个,莽出来再说。

然后又有问题了,我要把图片复制过来,那首先得判断该文件夹下有没有博文 Markdown 文件对应的文件夹吧……如果没有,我还得创建……

创建的文件夹得与博文 Markdown 文件同名。我已经创建测试文件夹成功了,完事后才发现在这儿获取不到该篇文章对应的 Markdown 文件的文件名。

因为 hexo-asset-image 实际上操作的是 hexo 生成的 public 下的 index.html 网页文件……

于是我尝试到 hexo 渲染 Markdown 为 HTML 的那儿去操作,正当我找到入口,准备大干一番时又发现个问题……插件那边的代码获取不到我在这儿找到的变量啊……

太麻烦了,遂放弃之。

PS:我的思路局限在「渲染时」或者「渲染后」,也许写个脚本直接处理 Markdown 博文,很简单就能做到吧……

ChangeLog

[2020-04-02-update]

PS:Typora@0.9.86(beta) 现在可以在设置里开启「插入图片时」,「复制图片到当前文件夹」等操作。而且和 PicGo 联动了,将来甚至可以插入图片时自动上传到云服务再返回链接吧。这就完美实现了我上面关于「引用本地图片」的想法啦!酷~


  1. 这是 Hexo 官方提供的:asset-folders ,不是插件提供的。其它静态资源的引用方式也可以看这个链接。 ↩︎