前言
之前想在博文里引用本地图片,按着随便搜到的教程无脑折腾了一番,当时记录了下步骤放在博文里,其实根本没搞懂。在 CSDN 上的备份经常被人访问,为了不误人子弟,稍微按自己的理解捋一下。
当然,也不一定正确。
先提一下,我目前的 hexo 版本为 4.0,其它版本可能会有不同。
引用本地图片与插件 hexo-asset-image
引用本地图片
首先要在 Hexo 博客配置添加一行[1]:
1 | # 开始使用本地静态资源 |
添加这行配置后,当你什么插件也没安装时,使用 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 | |-- /2019-12-23-hello-world |
理论上 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 | // 渲染后 |
所以我们在写博文引用图片时,就得把它们当作在一个文件夹下来处理,也就是引用的时候,要去掉文件夹路径。
最后渲染出来的效果是:
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 | npm install 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-asset
或 hexo-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 。这个插件会将 img
的 src
属性改为 data-src
。hexo-asset-image 的工作原理是统一处理 src
,没有对 data-src
等属性的判断,所以就不会处理图片。
我自己改了下,想提个 PR 来着,发现原插件仓库已经被归档了……
于是 fork 了一份:hqweay/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 联动了,将来甚至可以插入图片时自动上传到云服务再返回链接吧。这就完美实现了我上面关于「引用本地图片」的想法啦!酷~
这是 Hexo 官方提供的:asset-folders ,不是插件提供的。其它静态资源的引用方式也可以看这个链接。 ↩︎