php: воссоздать и отобразить изображение из двоичных данных

Можно ли воссоздавать изображения из двоичных данных (обрабатывать их при необходимости) и отображать их в одном скрипте? Что-то типа

// get and display image 1:
$imagedata1 = file_get_contents('assets/test.png');
$imagedata1 = process_using_gd_or_something($imagedata1);

echo "<img src={$imagedata1} >"; // <-- IS THIS (OR EQUIVALENT) POSSIBLE?

// get and display image 2:
//etc...

Я хочу избежать сохранения изображений на диск после обработки и получения их оттуда или использования внешнего скрипта...


person Cambiata    schedule 15.01.2010    source источник


Ответы (5)


Это можно сделать с помощью URI данных в атрибуте изображения src.

Формат: data:[<MIME-type>][;charset="<encoding>"][;base64],<data>

Этот пример взят прямо из страницы Википедии, посвященной URI данных:

<?php
function data_uri($file, $mime) 
{  
  $contents = file_get_contents($file);
  $base64   = base64_encode($contents); 
  return ('data:' . $mime . ';base64,' . $base64);
}
?>

<img src="<?php echo data_uri('elephant.png','image/png'); ?>" alt="An elephant" />
person Ben James    schedule 15.01.2010
comment
Спасибо Бен! Именно то, что мне было нужно! - person Cambiata; 15.01.2010
comment
Обратите внимание, что не все браузеры правильно отображают URI данных. Убедитесь, что вы хорошо протестировали его ... - person ircmaxell; 03.06.2011
comment
Небольшое замечание: я получил красноватое изображение вместо прозрачного. - person YOMorales; 10.07.2013
comment
Спасибо, Бен, именно то, что я искал. - person Abd Ul Aziz; 30.06.2014

На самом деле это возможно с помощью встроенных изображений (называемых URI данныхс).

Ваш тег изображения будет выглядеть примерно так:

<img src="data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub/
/ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcpp
V0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7" 
width="16" height="14" alt="embedded folder icon">

Почему в большинстве случаев это не очень хорошая идея:

  • Загрузка страницы будет замедлена, так как изображение должно быть загружено до полной HTML-структуры, которая может быть загружена и, следовательно, отображена. Тем более, если вы выполняете дополнительные операции над изображением. Ваш сайт, скорее всего, будет работать намного медленнее, чем если бы это было внешнее изображение.

  • Встроенные изображения должны быть закодированы в base64, что добавляет 33 % к их размеру.

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

person Pekka    schedule 15.01.2010

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

изображение.php

$imagedata1 = file_get_contents('assets/test.png');
$imagedata1 = process_using_gd_or_something($imagedata1);

header('Content-type: image/png');
echo $imagedata1;

другие_страницы.php:

echo "<img src='image.php?some_params'>";

РЕДАКТИРОВАТЬ: Извините, я пропустил уведомление о том, что мне не нужен внешний скрипт, но это решение более эффективно, чем кодирование изображения в base64.

person Krab    schedule 15.01.2010

Попробуй это...

$img=base64_encode($row['PICTURE']);

<img alt="105x105" class="img-responsive" src="data:image/jpg;charset=utf8;base64,<?php echo $img ?>"/>
person eildiz    schedule 23.09.2014

Если вам просто нужно изображение без html-кода вокруг него, вы можете использовать следующее:

$filename = 'assets/test.png';
$original_image = file_get_contents($filename);
$processed_image = process_the_image_somehow($original_image);

header('Content-type: '.mime_content_type($filename));
header('Content-Length: '.strlen($processed_image));
echo $processed_image;

Вы не должны забывать заголовок Content-Length, иначе он не будет работать. Вы также можете заменить mime_content_type(), так как согласно документам он устарел.

person riyad    schedule 02.07.2011