惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
T
Threat Research - Cisco Blogs
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 叶小钗
Security Latest
Security Latest
Spread Privacy
Spread Privacy
aimingoo的专栏
aimingoo的专栏
N
News and Events Feed by Topic
Webroot Blog
Webroot Blog
U
Unit 42
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Scott Helme
Scott Helme
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
T
The Blog of Author Tim Ferriss
A
About on SuperTechFans
爱范儿
爱范儿
S
Schneier on Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Schneier on Security
Schneier on Security
Latest news
Latest news
GbyAI
GbyAI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
The Register - Security
The Register - Security
WordPress大学
WordPress大学
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
PCI Perspectives
PCI Perspectives
Jina AI
Jina AI
AI
AI
NISL@THU
NISL@THU
I
Intezer
G
GRAHAM CLULEY
B
Blog
S
Secure Thoughts
IT之家
IT之家
宝玉的分享
宝玉的分享
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
有赞技术团队
有赞技术团队
V2EX - 技术
V2EX - 技术
Recorded Future
Recorded Future
Hacker News - Newest:
Hacker News - Newest: "LLM"

流动

对口型视频合成方案对比:Wav2Lip、VideoReTalking 与 MuseTalk 2026 音色克隆方案对比:IndexTTS-2、CosyVoice、GPT-SoVITS、Fish Speech、VoxCPM 部署与实测 AI Agent折腾记(OpenClaw / Hermes Agent) 我的2025年 大连之行 回家收麦 六一儿童节爬长城 Golang database/sql 数据库断线自动重连机制解析 Golang默认Http Client导致的cannot assign requested address错误 清明踏春,爬山看海 购入小牛G400T电动车 北京的三月飞雪 wrenAI本地LLM模型部署 天津一日游 2024年终总结 停止使用staticfile.org服务 使用 ImageMagick 自动添加水印,保护图片版权 如何注册一个.sol域名 奥森公园半日游 昌平42公里骑行绿道打卡 十月一日爬慕田峪长城 当Hugo遇上AVIF,优化图片加载 博客被恶意镜像 Github Pages 部署流程解析 搭建个人锻炼页面 你好 Follow 中秋爬山 Google Adsense的审核之旅 让你的IPFS站点持久在线:接入Filebase的Names(IPNS)服务 一次简短的青岛之行 解决 "undeclared name: any (requires version go1.18 or later)" 编译错误 搭建自托管IPFS Gateway服务,替代Cloudflare的IPFS Gateway 302跳转的跨域问题(CORS) GORM增加sqlcommenter特性 源码分析:GORM是如何生成sql的 工银亚洲网银密码重置 加速Cloudflare访问 2023年终总结 2023年12月北京暴雪记录 使用Hugo实现响应式和优化的图片 加速Google Analytics 使用Google Indexing API加速博客收录 在Netlify上部署Twikoo评论系统 利用Github Actions定时抓取微博 北大口腔牙周刮治记录 故乡回忆之旅 解决Golang使用go get安装包后找不到可执行文件的问题 修正Hugo的JSON Feed格式 我的学车之路 将博客部署到星际文件系统(IPFS) 新冠疫情后的第一个春节 第一次清理键盘 2022年终总结 去掉Cloudflare烦人的email-decode.min.js请求 优化博客的累计布局偏移(CLS)问题 将博客部署到Cloudflare Pages 奥林匹克公园向日葵之旅 记第二次洗牙 记录2022年海淀幼升小 Golang解析json的一个问题 疫情下的生活 整理下博客的一些调整 疫情下的五一假期 自己动手,更换thinkpad x1硬盘 二刷百望山 带娃游颐和园 博客架构说明 难得的清明假期 十一年的等待,终于拿到了liudon.com域名 被隔离的一周 mysql中字符串和整型自动转换的问题 一次惊心动魄的Mysql更新操作 如何在北京公积金网站上修改婚姻状况 PHP7.2编译安装后没有php.ini文件的问题 检测网站支持的SSL/TLS协议版本 记一次难忘的手术经历 十一假期经历 Swoft 框架运行分析(五) —— ConsoleProcessor模块分析 Swoft 框架运行分析(四) —— EventProcessor模块分析 一个git submodule update引发的问题 一个Curl的耗时长的问题 Swoft 框架运行分析(三) —— BeanProcessor模块分析 Swoft 框架运行分析(二) —— AnnotationProcessor模块分析 Swoft 框架运行分析(一) BCMath 与 科学计数 Flink Could Not Resolve Resourcemanager Address 解决Sublime Text安装包时"There Are No Packages Available for Installation"的报错 关于本站 2019,新开始
累计布局偏移修复方案改进 —— 自动生成图片宽高
Liudon · 2022-08-24 · via 流动

本站已不再采用本方案,新方案见使用Hugo实现响应式和优化的图片

遗留的问题

上一篇文章讲了我是如何解决博客累计布局偏移的问题,但是这个方案存在一个很大的问题。

手动输入每张图片的宽高

这就要求每次插入图片后,需要手动查看图片宽高,修改插入代码,导致整个流程变得繁琐,无法自动化。

身为一名工程师,对于这样一个痛点,势必要优化掉。

思路

发完上一篇文章后,我一直在想怎么能实现自动化插入图片宽高。

要插入的图片代码是类似这样的:

{{< figure src="https://static.liudon.com/img/cover-code.png" alt="cover.html code" width="2020" height="1468" >}}

我使用了picgo插件,上传图片到腾讯云对象存储,然后复制markdown图片代码插入文章。

能不能通过改造picgo插件,将上传后复制的代码,加上图片的宽高参数?

通过一番搜索,发现此方案不通,picgo确实支持自定义代码,但是变量仅支持文件名url

picgo config

此路不通,只好再想新的办法了。

对象存储的图片处理有接口,可以返回图片的宽高信息,详细说明见获取图片基本信息

能不能在生成文件的时候,通过发起一个请求拿到图片宽高,然后写入html代码?

经过一番搜索,发现hugo支持请求url,详细说明见Get Remote Data

{{ $dataJ := getJSON "url" }}
{{ $dataC := getCSV "separator" "url" }}

哈哈,柳暗花明又一村的感觉。

解决方案

此方案基于对象存储获取图片宽高,然后写入图片解析模板。

  1. 新增css配置

    新增如下配置,否则会导致图片变形。

    img {
        width:100%;
        height:auto;
    }
    
    figure {
        background-color: var(--code-bg);
    }
    
  2. 添加render-image.html文件

    代码如下:

    {{- $item := getJSON .Destination "?imageInfo&t=" now.Unix -}}
    {{/* 通过对象存储接口获取图片宽高,因为我使用了cdn,所以增加随机数保证拿到最新的图片宽高参数 */}}
    
    {{- $Destination := .Destination -}}
    {{- $Text := .Text -}}
    {{- $Title := .Title -}}
    
    {{- with $item }}
    <picture>
        <source type="image/webp" srcset="{{ $Destination | safeURL }}/webp" width="{{ .width }}" height="{{ .height }}">
        <img loading="lazy" src="{{ $Destination | safeURL }}" alt="{{ $Text }}" {{ with $Title}} title="{{ . }}" {{ end }} width="{{ .width }}" height="{{ .height }}" />
    </picture>
    {{- end -}}
    
  3. 添加cover.html文件

    代码如下:

    {{- with .cxt}} {{/* Apply proper context from dict */}}
    {{- if (and .Params.cover.image (not $.isHidden)) }}
    {{- $alt := (.Params.cover.alt | default .Params.cover.caption | plainify) }}
    <figure class="entry-cover">
        {{- $responsiveImages := (.Params.cover.responsiveImages | default site.Params.cover.responsiveImages) | default true }}
        {{- $addLink := (and site.Params.cover.linkFullImages (not $.IsHome)) }}
        {{- $cover := (.Resources.ByType "image").GetMatch (printf "*%s*" (.Params.cover.image)) }}
        {{- if $cover -}}{{/* i.e it is present in page bundle */}}
            {{- if $addLink }}<a href="{{ (path.Join .RelPermalink .Params.cover.image) | absURL }}" target="_blank"
                rel="noopener noreferrer">{{ end -}}
            {{- $sizes := (slice "360" "480" "720" "1080" "1500") }}
            {{- $processableFormats := (slice "jpg" "jpeg" "png" "tif" "bmp" "gif") -}}
            {{- if hugo.IsExtended -}}
                {{- $processableFormats = $processableFormats | append "webp" -}}
            {{- end -}}
            {{- $prod := (hugo.IsProduction | or (eq site.Params.env "production")) }}
            {{- if (and (in $processableFormats $cover.MediaType.SubType) ($responsiveImages) (eq $prod true)) }}
            <img loading="lazy" srcset="{{- range $size := $sizes -}}
                            {{- if (ge $cover.Width $size) -}}
                            {{ printf "%s %s" (($cover.Resize (printf "%sx" $size)).Permalink) (printf "%sw ," $size) -}}
                            {{ end }}
                        {{- end -}}{{$cover.Permalink }} {{printf "%dw" ($cover.Width)}}" 
                sizes="(min-width: 768px) 720px, 100vw" src="{{ $cover.Permalink }}" alt="{{ $alt }}" 
                width="{{ $cover.Width }}" height="{{ $cover.Height }}">
            {{- else }}{{/* Unprocessable image or responsive images disabled */}}
            <img loading="lazy" src="{{ (path.Join .RelPermalink .Params.cover.image) | absURL }}" alt="{{ $alt }}">
            {{- end }}
        {{- else }}{{/* For absolute urls and external links, no img processing here */}}
            {{- $item := getJSON .Params.cover.image "?imageInfo&t=" now.Unix -}}
            {{/* 通过对象存储接口获取图片宽高,因为我使用了cdn,所以增加随机数保证拿到最新的图片宽高参数 */}}
            {{- $coverUrl := .Params.cover.image -}}
            {{- with $item }}
            {{- if $addLink }}<a href="{{ $coverUrl | absURL }}" target="_blank"
                rel="noopener noreferrer">{{ end -}}
                <picture>
                <source type="image/webp" srcset="{{ $coverUrl | absURL }}/webp" width="{{ .width }}" height="{{ .height }}">
                <img loading="lazy" alt="{{ $alt }}" src="{{ $coverUrl | absURL }}" width="{{ .width }}" height="{{ .height }}">
                </picture>
            {{- end }}
        {{- end }}
        {{- if $addLink }}</a>{{ end -}}
        {{/*  Display Caption  */}}
        {{- if not $.IsHome }}
            {{ with .Params.cover.caption }}<p>{{ . | markdownify }}</p>{{- end }}
        {{- end }}
    </figure>
    {{- end }}{{/* End image */}}
    {{- end -}}{{/* End context */ -}}
    

使用方式和原来不变,插入markdown语法的图片代码即可。

![picgo config](picgo-config.png)

这下又可以愉快地码字了。