求一个图片缩放的 macro 的写法

想实现如下功能:

  • 如果图片大于 500px, 就缩放到 500px
  • 如果图片小于 500px, 就按图片的原始尺寸而不缩放

这样的 macro 如何写, 求指导.


不好意思, 没有说用途. org-mode 转成 html 上的页面上用.

讲清楚在哪里缩放, org-mode的inline图片还是image-mode的显示图片?

不好意思, org-mode 转成 html 上的页面上用.

你好,我要org-mode的inline解决方案。而且我的需求更简单,就统一宽度为500px就欧了。

我用

#+ATTR_HTML: :width 10%

#+ATTR_org: :500px

包括在.emacs中直接写死都没有办法。

后来查到说主机上需要安装ImageMagick才生效,是这样吗?

搜索论坛, 有很多讨论, 是要安装imagemagick才能生效

如果你会 css, 可以用css控制

哦, 你说org macro吧, 我还以为你想说elisp macro…

So try this

#+macro: sized-image @@html:<img height=$1 width=$2 src="$3" alt="$4" />@@

{{{sized-image(500px, 500px,
https://danbooru.donmai.us/data/sample/__original_drawn_by_deecha__sample-216216efef67d307d2bebe7f5ff4f0e0.jpg,
Test image)}}}

如何写一个带有类似条件判断的 org macro 呢? 带这种条件判断的, 我感觉无从下手. 可否指导一下查看什么资料?

  • 如果图片大于 500px, 就缩放到 500px
  • 如果图片小于 500px, 就按图片的原始尺寸而不缩放

你要这样智能判定, 用elisp和org-macro实现起来难度不是一般的大.

首先, org-macro起的不过是一个字符串替换的功能, 就算可以插入elisp, elisp也没法直接访问(除非你hack orgmode)org macro参数的值(只能访问到形如$1这样的标记).

更何况如果要用elisp要完成你这种的需求, 首先要获得图片的真实大小, 可能还需要调用imagemagick之类的库. 这样反而把问题复杂化.

那么我们换一个思路想, 如果你只需要导出html. 那我们完全可以在html文档里用javascript控制图片的大小, 比起用elisp来在导出阶段控制要更加方便和直观.

下面是代码实例, 我写的比较粗糙, 大小是写死的, 如果你会js, 可以仿照着改进一下

#+BEGIN_EXPORT html
<script lang="javascript">
// window.onload挂载的回调函数会在dom加载完成后被运行, 这时候我们的图片也加载完成了, 不怕我们访问不到他的属性
window.onload = function () {
  var imgs = document.getElementsByClassName("sized-image"); // 获取class为"sized-image"的所有对象, 我们用"sized-image"这个class来标记我们要控制 大小的图像
  for (i = 0; i < imgs.length; i++) {
    var imgObj = imgs[i] // document.getElementsByClassName返回所有具有特定class的数组, 我们用一个循环访问他的所有对象, 你就理解成elisp里的`dolist'
    imgObj.height = imgObj.naturalHeight > 500 ? 500 : imgObj.naturalHeight; // ?: 是js的三目运算符, 如果?前的求值结果为真, 则返回:前面的表达式, 否则返回:后面的表达式. naturalHeight是HTML5带来的一个新的img标签属性, 返回图像的原始高度, height指定图像的当前高度, 下同. 
    imgObj.width = imgObj.naturalWidth > 500 ? 500 : imgObj.naturalWidth;
  }
}
</script>
#+END_EXPORT

# 我们的图片宏
#+macro: sized-image @@html:<img class="sized-image" src="$1" alt="$2" />@@

# 该图片原始大小大于500x500
{{{sized-image(https://danbooru.donmai.us/data/sample/__original_drawn_by_deecha__sample-216216efef67d307d2bebe7f5ff4f0e0.jpg,
Test image)}}}

# 该图片大小小于500x500
{{{sized-image(https://raikou4.donmai.us/preview/21/62/216216efef67d307d2bebe7f5ff4f0e0.jpg,
small test image)}}}

例图

就是这样


Edit: 也可以考虑用css的max-heightmax-width优势是可以自动按比例缩放

#+macro: sized-image @@html:<img style="max-width:$1px; max-height:$2px; " class="sized-image" src="$3" alt="$4" />@@

{{{sized-image(200, 200, https://danbooru.donmai.us/data/sample/__original_drawn_by_deecha__sample-216216efef67d307d2bebe7f5ff4f0e0.jpg,
Test image)}}}

{{{sized-image(500, 500, https://raikou4.donmai.us/preview/21/62/216216efef67d307d2bebe7f5ff4f0e0.jpg,
small test image)}}}

TIM%E6%88%AA%E5%9B%BE20181130130237

2 个赞

感谢耐心回复, 感谢这么棒的思路!

请问你有什么开源项目吗, 我想小额捐赠以表感谢.

我只是个医学专业的学生,精力有限,搞不出什么厉害的开源项目 :smile:

如果老兄实在有心,不如请我喝杯可乐吧!

已捐赠, 请查收. 再次表示感谢!

1 个赞

wow!感谢!