Замена всех изображений в файле CSS на строки в кодировке base64 из командной строки - PullRequest
7 голосов
/ 29 марта 2011

В основном я пытаюсь написать умную единственную строку команд, которая выводит строки в кодировке 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. Убедиться в том, что есть только реальные пути и нет данных-юрис там, выходит за рамки:)

Я пытался заменить материал на sed, но я застрял в его ужасной документации. Нетрудно найти вхождения в шаблон url(…) в файле css, но бит между круглыми скобками должен быть заменен выводом вышеприведенной команды, и я не знаю, возможно ли это вообще. Так что, вот, помощь или несколько указателей (мне тоже нужно взглянуть на awk?) Будут очень благодарны! «Вы не можете сделать это без надлежащего сценария» также, конечно, будет:)

Ответы [ 4 ]

9 голосов
/ 29 марта 2011

С 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

Подтверждение концепции

См. ЗДЕСЬ для рабочего примера


С 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

Подтверждение концепции

См. ЗДЕСЬ для рабочего примера

0 голосов
/ 11 января 2018

Эта командная строка, которую я написал, вместо этого кодирует все изображения, содержащиеся в файле 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";
0 голосов
/ 29 марта 2011

У меня нет большого опыта работы с 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 действительно существуют
  • нет возможности указать выходной файл, запустите его как

pngReplacer pngFile ccsFile> newCcsFile

  • если в {} есть хиби-гэби, вы можете все это вырезать, прямо на '|' char как раз перед sed, и поместите $ 2 в конце команды sed.
  • Я был бы удивлен, если бы AIX sed мог обрабатывать выражение замены 280 символов, но у меня больше нет возможности его проверять. В общем, такие вещи хрупки.
  • самая большая хрупкость из всех, @ reg-exp @ replace-exp @ delimiter (@). Если вы получите знак @ в base64Str, то вам нужно будет найти символ для использования, которого нет в новом base64Str.

Надеюсь, это поможет.

0 голосов
/ 29 марта 2011

Подумайте об использовании Perl, а не sed.Пропустить awk в целом, это неудобно :-).(На самом деле это был один из первых языков программирования, которые я выучил, но Perl намного лучше).

Еще лучше, не делайте этого вообще, поскольку это не будет работать в 50% браузеров пользователей.В любом случае, будьте очень, очень уверены, что вам нет дела до этих пользователей, прежде чем сказать им об этом таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...