Отправка/отображение изображения с кодировкой base64

Мне нужно отправить base64 закодированную строку клиенту. Поэтому я открываю и читаю файл изображения на сервере, кодирую его и отправляю в браузер эти данные вместе с типом содержимого image/jpeg. Пример в php:

$image      = $imagedir . 'example.jpg';
$image_file = fopen($image, 'r');
$image_data = fread($image_file, filesize($image));

header("Content-type: image/jpeg");
echo 'data:image/jpeg;base64,' . base64_encode($image_data);

Clientside, я звоню:

var img     = new Image();
img.src     = "http://www.myserver.com/generate.php";
img.onerror = function(){alert('error');}
$(img).appendTo(document.body);

Это не работает по какой-то причине. onerror всегда срабатывает. Например, просмотр FireBug Network task говорит мне, что я получаю правильную информацию заголовка и правильное значение переданных байтов.

Если я отправлю эти данные как Content-type: text/plain, он работает, строка base64 отображается в браузере (если я вызываю script напрямую). Копирование и вставка этого вывода в элемент src элемента <img> показывает изображение, как ожидалось.

Что я здесь делаю неправильно?

Решение

Спасибо Pekka за то, что указали на мою ошибку. Вам не нужно (вы не можете!) Кодировать данные двоичного изображения как base64 в этом подходе. Без кодировки base64 он просто работает.

Ответы

Ответ 1

В этом случае нет оснований для того, чтобы base64 кодировал данные изображения в первую очередь. То, что вы хотите испустить, - это простые старые данные изображения.

Просто пропустите изображение JPEG как есть.

Единственный способ, который имел бы для меня смысл, - это захватить вывод generate.php с помощью вызова AJAX и напрямую передать результат в свойство src. Это должно работать (хотя и не в IE < 8, но я уверен, что вы это знаете). Но если вы можете вызвать generate.php непосредственно в качестве источника изображения, я не вижу необходимости в этом.

Ответ 2

Если вы задаете тип контента для изображения /jpeg, вы должны указать только данные jpeg без бремени base64. Но вы обрабатываете результат так, как если бы он был html.

Вы эффективно создаете данные uri, что хорошо, но, как вы отметили, только как uri. Поэтому оставьте тип контента таким, как он есть (text/html), и

echo '<img src="data:image/jpeg;base64,'.base64_encode($image_data).'">';

и вам хорошо идти.

Ответ 3

Я считаю, что это можно сделать довольно эффективно, просто используя только php... вы можете использовать приведенную ниже функцию для рендеринга изображений в кодированных base64 данных

    function binaryImages($imgSrc,$width = null,$height = null){
    $img_src = $imgSrc;
    $imgbinary = fread(fopen($img_src, "r"), filesize($img_src));
    $img_str = base64_encode($imgbinary);

    if(isset($height) && isset($width))
    {
    echo '<img src="data:image/jpg;base64,'.$img_str.'" height="'.$height.'" width="'.$width.'"/>';
    }
    else
    {
    echo '<img src="data:image/jpg;base64,'.$img_str.'"/>';
    }
}

как использовать эту функцию

    binaryImages("../images/end.jpg",100,100); 

запустить функцию binaryImages. Первый параметр - путь изображения, второй - ширина, а затем высота... высота и ширина необязательны

Ответ 4

я бы порекомендовал: base64_encode Кодирует данные с MIME base64

echo '<img src="data:image/jpeg;base64,'.base64_encode($image).'">';