使用命令行中的base64编码字符串替换CSS文件中的所有图像

时间:2011-03-28 21:44:42

标签: css command-line sed base64

基本上我正在尝试编写一个聪明的单行命令,它输出base64编码的字符串来代替以前用作图像路径的位置。所以:

background-image: url(path/to/my/image.png);

......会变成:

background-image: url(data:image/png;base64,ABvR0…+tC==);

我通常通过以下方式将图像转换为base64编码的字符串:

openssl enc -base64 -in path/to/my/image.png

哪个输出base64 ...但是有新行。通过tr管道来解决这个问题,例如:

openssl enc -base64 -in path/to/my/image.png | tr -d '\n'

只输出一个长base64编码的字符串。通过使用pbcopy(在Mac OS上)发送到剪贴板,如下所示:

openssl enc -base64 -in path/to/my/image.png | tr -d '\n' | pbcopy

非常适合使用base64表示替换偶然的图像,但我想要做的是自动替换文件中所有出现的url(path/to/whatever.ext)各自的base64字符串。确保只有实际路径并且没有数据 - uris在这里超出范围:)

我一直在尝试用sed替换内容,但我陷入了可怕的文档中。在css文件中找到url(…)模式的出现并不是很困难,但是括号之间的位需要被上面命令的输出所取代,如果可能的话,我也无能为力。所以,它是,帮助或一些指针(我是否也需要查看awk?)将不胜感激!如果没有合适的脚本,你就不能这样做“当然也会这样做:)

4 个答案:

答案 0 :(得分:9)

使用openssl工具

#!/bin/bash

awk -F'[()]' -v q="'" '

/background-image: url(.*)/ {
  cmd=sprintf("openssl enc -base64 -in %s | tr -d %c\\n%c",$2,q,q)
  cmd | getline b64
  close(cmd)
  $0=$1 "(data:image/png;base64," b64 ");"
}1' /path/to/css/file

概念证明

有关工作示例,请参阅HERE


使用base64工具

#!/bin/bash

awk -F'[()]' '

/background-image: url(.*)/ {
  cmd=sprintf("base64 -w0 %s",$2)
  cmd | getline b64
  close(cmd)
  $0=$1 "(data:image/png;base64," b64 ");"
}1' /path/to/css/file

概念证明

有关工作示例,请参阅HERE

答案 1 :(得分:0)

考虑使用Perl而不是sed。完全跳过awk,它很尴尬:-)。 (实际上它是我学过的第一种编程语言之一,但Perl要好得多)。

更好的是,不要这样做,因为它不会在50%的用户浏览器中运行。无论如何,在你以这种方式告诉他们之前,要非常非常确定你不关心这些用户。

答案 2 :(得分:0)

我对ccs和png文件没有很多经验,但鉴于你的非常有用 我有这个字符串,我想要那个字符串描述,这是一个初稿

#! /bin/ksh # -vx  (bash should work too)

usageMsg="pngReplacer pngFile ccsFile"
case $# in
  [!2] ) print "usage: ${usageMsg}"  ; exit 1
esac
set -- ${@}  # I'm surprised that we need this line
base64Str=$(openssl enc -base64 -in "$1" 2>/dev/null | tr -d '\n')

{
   if ${testMode:-false} ; then
        print -- " background-image: url(path/to/my/image.png);"
   else 
        cat "$2"
   fi
} | sed 's@url(.*)@url(data:image/png;base64,'"$base64Str"')@g'

这里有很多脆弱性

  • 我有这个权利,png文件和css文件,对吧?
  • 你知道ksh / bash $ 1 $ 2等参数,对吧?
  • 参数计数测试没问题,但是
  • 你可能真的想确认$ 1和$ 2确实存在
  • 没有机会指定outputFile,将其作为
  • 运行

pngReplacer pngFile ccsFile> newCcsFile

  • 如果{}中的东西给你heebie-geebies,你可以把它全部切掉,直到'|'在sed之前的char,并将$ 2放在sed命令的末尾。
  • 如果AIX sed可以处理280个char替换表达式,我会感到惊讶,但我不再需要它进行测试了。一般来说,seds对这类事情很脆弱。
  • 最大的脆弱性,@ reg-exp @ replace-exp @ delimiter(@)。如果你在base64Str中找到一个@符号,那么你将不得不找到一个不在新的base64Str中使用的字符。

我希望这会有所帮助。

答案 3 :(得分:0)

我编写的这个命令行改为编码包含在HTML文件中的所有图像。

它可以很容易地适用于编码CSS文件中的所有图像(通过编辑 base64images 函数)。

它只需要PHP命令行解释器。

#!/usr/bin/php
<?php
    /**
     * This command line tool encodes all images contained in the specified HTML file.
     * The encoded contents will be returned on standard output.
     * Use redirection to store it into a file.
     * @author Massimiliano Alessandri <m.alessandri@spaziocolore.it>
     */
    /**
     * Converts a "src" property embedding the referenced image.
     * This way, the recipient won't have to click on "display images" to view the images.
     * @param array $matches the array sent by the preg_replace_callback function
     * @return string the encoded "src" property
     */
    function base64images($matches) {
            return 'src="data:'.mime_content_type($matches[1]).';base64,'.base64_encode(file_get_contents($matches[1])).'"';
    }
    if($argc < 2) {
        echo 'Usage: '.$argv[0].' [file to be encoded]';
        echo 'The encoded file will be returned to standard output.';
        exit;
    }
    $filename = $argv[1];
    if(file_exists($filename))
        echo preg_replace_callback('/src="([^"]+)"/', 'base64images', file_get_contents($filename));
    else
        echo 'File not found: '.$filename."\n";