2016-06-13 5 views
0

Я сделал этот код для генерации данных URI для прозрачного PNG заданного размера:Как создать максимально возможный прозрачный png/gif заданного размера в PHP?

function createTransparentDataURI($w = 1, $h = 1) { 

    // Enable output buffering 
    ob_start(); 

    $img = imagecreatetruecolor($w, $h); 
    imagesavealpha($img, true); 
    $color = imagecolorallocatealpha($img, 0, 0, 0, 127); 
    imagefill($img, 0, 0, $color); 
    imagepng($img); 
    imagedestroy($img); 

    // Capture the output 
    $imagedata = ob_get_contents(); 
    // Clear the output buffer 
    ob_end_clean(); 

    // REF: http://stackoverflow.com/questions/9370847/php-create-image-with-imagepng-and-convert-with-base64-encode-in-a-single-file 
    return 'data:image/png;base64,' . base64_encode($imagedata); 
} 

Пример запуска с

echo createTransparentDataURI(1016, 312); 

возвращается

данных: изображение/PNG; base64, iVBORw0KGgoAAAANSUhEUgAAA/gAAAE4CAYAAADvrFgKAAAE40lEQVR4nO3BAQ0AAADCoPdPbQ8HFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwZltVAAEv7IggAAAAAElFTkSuQmCC

Есть ли способ, чтобы «сжать» (PNG сжатие без потерь, но с опцией сжатия?) Эти данные URI-с лучшим кодированием или с использованием одного цвета GIF? Программная графика с PHP не самая сильная область.

+0

Вот хорошие новости. Ваш оригинальный PNG составляет 1308 байт, но просто повторно сохраняет его с помощью Photoshop в качестве 2-цветного GIF, приносит размер до 918 байт, и, что еще лучше, повторное сохранение его в виде 2-цветного PNG позволяет снизить его до 459 байт. (Это включает в себя 37-байтную марку, хотя я * специально * сказал PS, чтобы не сохранить ее.) Очевидной первой оптимизацией было бы * не * создать ваше изображение как «32-битное RGB + альфа», но с более низким глубина цвета. – usr2564301

+0

@RadLexus. Хорошо знать, что можно уменьшить размер. Эти фиктивные изображения создаются «на лету»/кэшируются, чтобы быть встроенными с некоторым возможным HTML. Они должны выполняться на PHP без CLI. Любые предложения по изменению кода в моем вопросе? – Drakes

ответ

3

Учитывая, что изображение будет прозрачным, и на нем ничего не появится, вам не понадобится его без потерь. Это означает, что вы можете использовать цветовую палитру одного цвета, которая создаст индекс для этого цвета и будет использовать индекс для всех пикселей на изображении. Чтобы создать индексную палитру PNG, вы должны использовать функцию imagetruecolortopalette() в вашем коде: http://php.net/manual/en/function.imagetruecolortopalette.php

Вы также можете установить максимальный уровень сжатия изображения.

function createTransparentDataURI($w = 1, $h = 1) { 
    //... 
    //create image palette with one color, the dithering (the second argument) doesn't matter here 
    imagetruecolortopalette($img, false, 1); 
    imagepng($img, null, 9); //set the compression level to highest 
    //... 
} 

Это уменьшило длину данных 1016x312 изображения от 1308 до 133 байт, что почти в десять раз.

Путем преобразования двоичных данных в base64 вы можете увидеть невооруженным глазом, что есть место, чтобы сжать, что тоже:

iVBORw0KGgoAAAANSUhEUgAAA/gAAAE4AQMAAADVYspJAAAAA1BMVEUEAgSVKDOdAAAAPUlEQVR42u3BAQ0AAADCoPdPbQ8HFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/BicAAABWZX81AAAAABJRU5ErkJggg ==

, где несколько " A "-

Вы можете включить http-gsip-сервер, чтобы сжать этот ответ еще больше.

GIF не улучшится, так как размер моего теста составил 910 байт.

+0

Абсолютно красиво! Отлично работает. Большое спасибо. – Drakes

Смежные вопросы