Markdown Image Hosting-Free Solution: Base64 Support from Obsidian to Hugo
Obsidian #
长期以来,Markdown写作的最大痛点在于图片管理。
传统方案需要:
- 截图 → 保存到指定文件夹
- 手动插入相对路径
- 同步时确保图片路径一致
尽管多数Markdown编辑器都能进行图片路径的自动化托管,但仍未解决attachment冗余存储问题。
偶然想到,能否直接将图片转为 Base64 字符串嵌入Markdown?搜索后发现,有款Obsidian插件Image-Inline正好实现了这个功能。
"About: Paste your image without attachment files."
优缺点权衡 #
| 指标 | 优势 | 注意事项 |
|---|---|---|
| 部署流程 | 无需图床配置 | 单篇文章体积增大20%-30% |
| 可移植性 | 文件自包含,无外部依赖 | 浏览器缓存利用率降低 |
| 安全性 | 规避外链失效风险 | 不支持HTTP/3的服务器加载变慢 |
设定示例 #
Hugo #
部署报错 #
我在使用 Hugo 和 Blowfish 主题部署博客到 Cloudflare Pages 时,新增一篇含 Base64 图片的文章后,遇到了构建错误:
Error: error building site: "/opt/buildhome/repo/themes/blowfish/layouts/_default/_markup/render-image.html:14:23": execute of template failed: template: _default/_markup/render-image.html:14:23: executing "_default/_markup/render-image.html" at <resources.GetMatch>: error calling GetMatch: runtime error: invalid memory address or nil pointer dereference
问题原因 #
通过分析Blowfish主题的图片模板 (layouts/_default/_markup/render-image.html),发现它只支持两种图片来源:
- 外部链接(如
https://) - 本地文件(位于
/content或/static)
而Base64字符串 (例如 data:image/png;base64,xxxxxxx/xxxxxx) 既不是 URL,也不是本地文件,导致模板调用 resources.GetMatch 时崩溃。
解决方案 #
Hugo 支持模板覆盖,只需在项目根目录创建自定义模板即可解决问题。
- 创建自定义模板:
# 创建模板目录
mkdir -p layouts/_default/_markup/
# 复制主题的渲染模板到根目录进行修改
cp themes/blowfish/layouts/_default/_markup/render-image.html layouts/_default/_markup/
- 修改模板支持 Base64:
在模板中添加对data:image/的识别,直接渲染 Base64 图片。修改后的核心代码如下:
/*代码由DeepSeek R1生成*/
{{- $disableImageOptimization := .Page.Site.Params.disableImageOptimization | default false }}
{{- $url := urls.Parse .Destination }}
{{- $altText := .Text }}
{{- $caption := .Title }}
{{/* 新增:Base64图片处理 - 放在最前面 */}}
{{- if hasPrefix .Destination "data:image/" }}
<figure>
<img class="my-0 rounded-md" loading="lazy" src="{{ .Destination | safeURL }}" alt="{{ $altText }}" />
{{ with $caption }}<figcaption>{{ . | markdownify }}</figcaption>{{ end }}
</figure>
{{- else }}
{{/* 原外部链接处理(保留) */}}
{{- if findRE "^https?" $url.Scheme }}
<figure>
<img class="my-0 rounded-md" loading="lazy" src="{{ $url.String }}" alt="{{ $altText }}" />
{{ with $caption }}<figcaption>{{ . | markdownify }}</figcaption>{{ end }}
</figure>
{{- else }}
{{/* 原本地资源处理(保留) */}}
{{- $resource := "" }}
{{- if $.Page.Resources.GetMatch ($url.String) }}
{{- $resource = $.Page.Resources.GetMatch ($url.String) }}
{{- else if resources.GetMatch ($url.String) }}
{{- $resource = resources.Get ($url.String) }}
{{- end }}
{{- with $resource }}
<figure>
{{- if or $disableImageOptimization (eq .MediaType.SubType "svg")}}
<img
class="my-0 rounded-md"
loading="lazy"
src="{{ .RelPermalink }}"
alt="{{ $altText }}"
/>
{{- else }}
<img
class="my-0 rounded-md"
loading="lazy"
srcset="
{{ (.Resize "330x").RelPermalink }} 330w,
{{ (.Resize "660x").RelPermalink }} 660w,
{{ (.Resize "1024x").RelPermalink }} 1024w,
{{ (.Resize "1320x").RelPermalink }} 2x"
src="{{ (.Resize "660x").RelPermalink }}"
alt="{{ $altText }}"
/>
{{- end }}
{{ with $caption }}<figcaption>{{ . | markdownify }}</figcaption>{{ end }}
</figure>
{{- else }}
<figure>
<img class="my-0 rounded-md" loading="lazy" src="{{ $url.String }}" alt="{{ $altText }}" />
{{ with $caption }}<figcaption>{{ . | markdownify }}</figcaption>{{ end }}
</figure>
{{- end }}
{{- end }}
{{- end }} {{/* 新增:结束Base64的判断 */}}
改动说明:
- 在最前面检查 Base64 格式(
data:image/),直接渲染。 - 使用
safeURL确保 Base64 字符串安全输出。 - 保留原有的外部链接和本地文件处理逻辑。
- 部署验证:
提交修改后,推送至 GitHub,Cloudflare Pages 自动构建成功,Base64 图片正常显示。
标签: #Markdown #Obsidian #Hugo #Base64 #Cloudflare
相关工具推荐:
- Image-Inline:Obsidian 插件,将图片转为 Base64 编码。
- Hugo:快速静态网站生成器。
- Blowfish:轻量且现代的 Hugo 主题。
文档参考: