首页 > 解决方案 > 批量 base64 图像解码

问题描述

我有一个大的 (117MB!) html 文件,其中包含数千张编码为 base64 的图像,我想将它们解码为 JPG,但我的 bash-fu 不足以做到这一点,而且我无法做到网上找答案

标签: htmlbashbase64jpeg

解决方案


一般来说,HTML 不能用正则表达式正确解析,但如果你有特定的有限格式,那么它可以工作。

给定一个简单的格式,例如

<body>
<img src="data:image/jpeg;base64,DpFDPGOIg3renreGR43LGLJKds==">
<img src="data:image/jpeg;base64,DpFDPGOIg3renreGR43LGLJKds=="><img src="data:image/jpeg;base64,DpFaPGOIg3renreGR43LGLJKds==">
<div><img src="data:image/jpeg;base64,DpFdPGOIg3renreGR43LGLJKds=="></div>
</body>

下面可以拉出数据

i=0; awk 'BEGIN{RS="<"} /="data:image\/jpeg;base64,[^\"]*"/ { match($0, /="data:image\/jpeg;base64,([^\"]*)"/, data); print data[1]; }' test.html | while read d; do echo $d  | base64 -d > $i.jpg; i=$(($i+1)); done

打破它:

i=0保留一个计数器,以便我们可以为每个图像输出不同的文件名。

awk 'BEGIN{RS="<"}运行 awk 并将记录分隔符从默认换行符更改为 <,因此我们始终将每个 HTML 元素视为单独的记录。

/="data:image\/jpeg;base64,[^\"]*"/仅对嵌入了 base64 jpeg 数据的记录运行以下命令。

{ match($0, /="data:image\/jpeg;base64,([^\"]*)"/, data); print data[1]; }'拉出数据本身,逗号和尾引号之间的括号匹配的部分,然后打印。

test.html只是输入文件名。

| while read d; do将输出 base64 数据通过管道传输到循环。read将每一行放入d,直到没有更多的输入。

echo $d | base64 -d > img$i.jpg;将当前图像通过 base64 解码器并将输出存储到文件中。

i=$(($i+1));增量更改下一个文件名。

done完毕。

这里有几件事可能会做得更好:

  • 应该有一种方法可以让行匹配正则表达式直接捕获base64数据,而不是在调用match()函数时重复正则表达式,但我无法让它工作。
  • 我不喜欢将管道读入变量 d 的技术,只是将其回显到另一个管道 - 直接通过管道会更好 - 但base64不知道只使用输入的一行。
  • 出于某种原因,我还没有弄清楚,直接在使用它的地方增加计数器(即echo $d | base64 -d > img$((i++)).jpg)只写入第一个文件,即使echo $d > img$((i++)).b64正确地将编码数据写入多个文件。我没有等待解决这个问题,而是将增量拆分为它自己的命令。

推荐阅读