|
|
|
| Задача: проверить GIF - изображение на присутствие в ней анимации!
Вопрос: как это сделать средствами РНР?
Просто при использовании фотогалереи разработчиков этого сайта, возникают проблемы при загрузке анимированых gif - изображений. | |
|
|
|
|
|
|
|
для: Artemy
(14.02.2006 в 17:25)
| | Господин Голышев, может Вы мне поможете? | |
|
|
|
|
|
|
|
для: Artemy
(15.02.2006 в 10:13)
| | Хелп? | |
|
|
|
|
|
|
|
для: Artemy
(15.02.2006 в 14:26)
| | Хоть бы кто ответил, что не знает? | |
|
|
|
|
|
|
|
для: Artemy
(15.02.2006 в 16:13)
| | а какие проблемы возникают при загрузке gif? он не грузится вообще? или перестает
дрыгаться? может, это из-за функций resize? я, если честно, галерею скачала, но не
смотрела еще, руки не дошли. но, по-моему, gif что анимированный, что нет - никакой
разницы...
или из-за водяных знаков... вот тут - в последней строке....
===============================
PhotoWatermark.Professional.6.0.3.3.Retail.With.Frames
Обновилась до версии 6.0.3.3 программа для нанесения водяных знаков на изображения. В своём роде можно сказать занимает лидирующие позиции. Мoжно делать массовое наношение, то есть выбираем папку и помечаем все изображения в ней своим водяным значком. Можно также добавить дату, что может хорошо помочь при выставлении даты на фотографиях. В новой версии исправлены баги связаные с сохранением анимированых gif файлов. | |
|
|
|
|
|
|
|
для: elenaki
(15.02.2006 в 16:30)
| | Некоторые анимированные гифки копируются, а не которые нет!
Хотелось бы проверять загружаемые изображения на наличие анимации. | |
|
|
|
|
|
|
|
для: Artemy
(15.02.2006 в 17:10)
| | Для этого придется самому разобрать содержимое GIF-потока, чтобы сосчитать имеющиеся в нем дескрипторы изображений.
Довольно мерзкое и не самое быстрое занятие. Хотя и реализуемое.
Хотя... наверное можно, обнаружив второй дескриптор, прекратить разбор. | |
|
|
|
|
|
|
|
для: Trianon
(15.02.2006 в 20:53)
| | Пришлось поточить вот этот (http://www.w3.org/Graphics/GIF/spec-gif89a.txt) документ, покурить бамбук, слегка попотеть.
Но в целом вышло что-то такое.
Дескрипторы изображений находятся в элементах $gif['stream'][ nnn ]['id'] == '2C'
<?php
function getstr(&$strm, $len = 1)
{ $v = substr($strm, 0, $len); $strm = substr($strm, $len); return $v; }
function getvstr(&$strm) { return getstr($strm, getbyte($strm)); }
function getbyte(&$strm) { return ord(getstr($strm,1)); }
function getword(&$strm) {$a = getbyte($strm); return $a + (getbyte($strm) << 8); }//>>
function get_localscreendescriptor(&$strm)
{
$lsd0 = getstr($strm, 7);
$pkd = ord($lsd0{4}); $gctf = 1&($pkd >>7); $gcts = 3<< (1+($pkd&7)); // >>
$lsd = array('info' => $lsd0);
if($gctf)
$lsd['colors'] = getstr($strm, $gcts);
return $lsd;
}
function get_imagedescriptor(&$strm)
{ // assume 2C introducer already read
$imd0 = getstr($strm, 9);
$pkd = ord($imd0{8}); $lctf = 1&($pkd >>7); $lcts = 3<< (1+($pkd&7)); //>>
$imd = array('info' => $imd0);
if($lctf)
$imd['colors'] = getstr($strm, $lcts);
return $imd;
}
function get_gif(&$strm)
{
$g = array();
$g['head'] = array('type'=>getstr($strm, 3), 'version' =>getstr($strm, 3)) ;
$g['lsd'] = get_localscreendescriptor($strm);
$g['stream']= array();
$last_block;
while(($id= getbyte($strm)) != 0)
{
$blk = array('id'=> sprintf("%02X",$id));
switch($id)
{
case 0x3B: break;
case 0x2C:
$blks = array();
$blk['imd'] = get_imagedescriptor($strm, $blk);
$blk['minLZW'] = getbyte($strm);
while(strlen($blks[]=getvstr($strm))!= 0) ;
$blk['chunks']=$blks;
break;
case 0x21:
$block = getbyte($strm);
$blks = array('sub_id' => sprintf("%02X",$block), 'rec' => array());
while(strlen($blks['rec'][] = getvstr($strm)) != 0) ;
$blk['ext'] = $blks;
break;
}
$g['stream'][] = $blk;
}
return $g;
}
$gif1 = @file_get_contents("example.gif");
echo "<pre>";
$gif = get_gif($gif1);
print_r($gif);
?>
|
| |
|
|
|
|
|
|
|
для: Trianon
(16.02.2006 в 15:03)
| | Большое Вам спасибо!
А что делать с этими дискрипторами? | |
|
|
|
|
|
|
|
для: Artemy
(16.02.2006 в 15:30)
| | Если их два и более - значит GIF содержит 2 и более кадра. Значит GIF анимирован. Если только один - значит обычная картинка.
Вы же это хотели выяснить?
PS В принципе, после обнаружения второго такого дескриптора анализ можно было бы и прервать. Можно также не собирать графические данные(chunks) и данные блоков расширения (rec). | |
|
|
|
|
|
|
|
для: Trianon
(16.02.2006 в 15:33)
| | хм...Я пробовал анимированным гифом провести "такого рода махинации", который состоит из трех кадров. И я не нашел там такого элемента - stream. | |
|
|
|
|
|
|
|
для: Artemy
(16.02.2006 в 16:32)
| | А какие элементы там нашлись?
Прикрепите, пожалуйста, этот gif к ответу. Я его гляну. | |
|
|
|
|
|
|
|
для: Trianon
(16.02.2006 в 16:47)
| | Прикрепил! | |
|
|
|
|
|
|
|
для: Artemy
(16.02.2006 в 16:50)
| | Я имел в виду - прикрепить сам gif-файл, а не отчет скрипта. :))) | |
|
|
|
|
 37.8 Кб |
|
|
для: Trianon
(16.02.2006 в 17:06)
| | Вауля! :) | |
|
|
|
|
|
|
|
для: Artemy
(16.02.2006 в 17:10)
| | У меня честно пишет Total frames: 3
То бишь в GIFе всего три кадра. | |
|
|
|
|
|
|
|
для: Trianon
(16.02.2006 в 17:06)
| | Попробуйте этот вариант.
<?php
function getstr(&$strm, $len = 1)
{ $v = substr($strm, 0, $len); $strm = substr($strm, $len); return $v; }
function getvstr(&$strm) { return getstr($strm, getbyte($strm)); }
function getbyte(&$strm) { return ord(getstr($strm,1)); }
function getword(&$strm) {$a = getbyte($strm); return $a + (getbyte($strm) << 8); }//>>
function get_localscreendescriptor(&$strm)
{
$lsd0 = getstr($strm, 7);
$pkd = ord($lsd0{4}); $gctf = 1&($pkd >>7); $gcts = 3<< (1+($pkd&7)); // >>
$lsd = array('info' => $lsd0);
if($gctf)
$lsd['colors'] = getstr($strm, $gcts);
return $lsd;
}
function get_imagedescriptor(&$strm)
{ // assume 2C introducer already read
$imd0 = getstr($strm, 9);
$pkd = ord($imd0{8}); $lctf = 1&($pkd >>7); $lcts = 3<< (1+($pkd&7)); //>>
$imd = array('info' => $imd0);
if($lctf)
$imd['colors'] = getstr($strm, $lcts);
return $imd;
}
function get_gif(&$strm)
{
$g = array();
$g['frames'] = 0;
$g['head'] = array('type'=>getstr($strm, 3), 'version' =>getstr($strm, 3)) ;
$g['lsd'] = get_localscreendescriptor($strm);
$g['stream']= array();
$last_block;
while(($id= getbyte($strm)) != 0)
{
$blk = array('id'=> sprintf("%02X",$id));
switch($id)
{
case 0x3B: break;
case 0x2C: $g['frames']++;;
$blks = array();
$blk['imd'] = get_imagedescriptor($strm, $blk);
$blk['minLZW'] = getbyte($strm);
while(strlen($blks[]=getvstr($strm))!= 0) ;
$blk['chunks']=$blks;
break;
case 0x21:
$block = getbyte($strm);
$blks = array('sub_id' => sprintf("%02X",$block), 'rec' => array());
while(strlen($blks['rec'][] = getvstr($strm)) != 0) ;
$blk['ext'] = $blks;
break;
}
$g['stream'][] = $blk;
}
return $g;
}
$gif1 = @file_get_contents("example.gif");
$gif = get_gif($gif1);
echo "Total frames: ".$gif['frames']."<br>\r\n";
?>
|
| |
|
|
|
|
|
|
|
для: Trianon
(16.02.2006 в 17:13)
| | ОГРОМНОЕ СПАСИБО!!! :-)
Все работает! | |
|
|
|