2013-06-15 4 views
0

애니메이션 GIF의 크기를 조정하고 PHP에서 imagick 확장명을 사용하여 배경을 추가했습니다. 애니메이션 gif의 크기를 조정할 때 imagick 성능 향상

내가 사용하고있는 코드입니다 :

$image = new Imagick('myfile.gif'); 
$image = $image->coalesceimages(); 

$final = new \Imagick(); 

foreach ($image as $frame){ 

    $frame->thumbnailImage($width, $height, true); 
    $geometry = $image->getImageGeometry(); 

    $x = ($width - $geometry['width'])/2; 
    $y = ($height - $geometry['height'])/2; 

    $canvas = new \Imagick(); 
    $canvas->newImage($width, $height, $background); 

    $canvas->compositeImage($image, \Imagick::COMPOSITE_OVER, $x, $y); 

    $final->addimage($canvas); 
} 

$final->desconstructimages(); 
$final->writeImages('resized.gif', true); 

코드 작품과 크기가 조정 된 이미지는 완벽하다. 그러나 애니메이션 GIF의 크기를 조정할 때는 꽤 오래 걸립니다.

위의 코드를 사용하면 36kb gif의 크기를 60 프레임으로 조정하는 데 약 10 초가 소요됩니다. 애니메이션이 아닌 이미지의 경우 약 0.5 초가 소요됩니다.

나는 Ubuntu 12.10 32-bitImageMagick 6.8.1-0 2012-12-20을 실행 중입니다.

어쨌든 크기를 빠르게하려면?

업데이트 :

내가 thumbnailImage는 모든 프레임에 호출 할 필요가 없다는 것을 발견, 그래서 이것은 내가 사용하고 무엇을 지금 : 한 번만 thumbnailing을함으로써

$image = new Imagick('myfile.gif'); 
$image = $image->coalesceimages(); 

$final = new \Imagick(); 

$image->thumbnailImage($width, $height, true); 
$geometry = $image->getImageGeometry(); 

$x = ($width - $geometry['width'])/2; 
$y = ($height - $geometry['height'])/2; 

foreach ($image as $frame){ 

    $canvas = new \Imagick(); 
    $canvas->newImage($width, $height, $background); 

    $canvas->compositeImage($image, \Imagick::COMPOSITE_OVER, $x, $y); 

    $final->addimage($canvas); 
} 

$final->desconstructimages(); 
$final->writeImages('resized.gif', true); 

, 나는 지금 평균에 1 초 (10 %!)를 절약하고 있습니다! 따라서 성과에 만족해야하고 불평하지 않아야한다고 말한 사람에게 이것은 이전에 행복했던 것을 조사하고 개선해야한다는 증거입니다. 그렇지 않으면 항상 평범한 개발자가 될 것입니다.

나는 물론 변환 시간을 줄이려고 노력하고 있으며 어떤 호출이 가장 비싸고 어떤 대상인지 결정하기 위해 프로파일 링을 수행 할 것입니다.

답변

2

일을 최적화하는 동안 지출 한 후 약 6.5 초의 평균 시간으로 끝났는데 이는 초기 10 초보다 훨씬 좋습니다.

이제 루프 외부에서 애니메이션의 크기를 조정하고 deconstructImages보다 빠른 optimizeImageLayers을 사용하고 파일 크기를 줄입니다.

$image = new Imagick('myfile.gif'); 
$image = $image->coalesceimages(); 

$final = new \Imagick(); 

foreach ($image as $frame){ 

    $image->thumbnailImage($width, $height, true); 
    $geometry = $image->getImageGeometry(); 

    $x = ($width - $geometry['width'])/2; 
    $y = ($height - $geometry['height'])/2; 

    $canvas = new \Imagick(); 
    $canvas->newImage($width, $height, $background); 

    $canvas->compositeImage($image, \Imagick::COMPOSITE_OVER, $x, $y); 

    $final->addimage($canvas); 
} 

$final = $final->optimizedImageLayers(); 
$final->writeImages('resized.gif', true); 

이 현재 내가 사용하고 그것으로 매우 기쁘게 생각하고 것입니다. 그러나, 나는 imagemagick의 설정을 조정하고 색상 수심을 가지고 놀아서, 더 나은 시간을 가지기를 기대한다. :)

-2

60 프레임의 크기를 조정할 때 10 초가 소요되는 경우 각 프레임은 실제로 1/6th 초가 걸리므로 1 프레임의 결과는 더 좋지 않습니까? 60 시간 더 일할 때 조금 더 오래 걸리면 불평해서는 안됩니다.

+0

글쎄, 그렇다고 생각하면 그렇게 나쁘지 않습니다. 그러나 아마도 더 효율적인 방법이있을 수 있습니다. 현재 각 프레임을 루프에서 처리하고 있지만 더 잘할 수있는 최적화 된 방법이 있거나 다른 사람이 이전에이 작업을 수행하고이를 수행하는보다 효율적인 방법을 발견했을 수 있습니다.현재 실적에 만족한다는 점에 대해서는 동의하지 않습니다;) 개발자는 실적, 수익 또는 기타 다른 분야에서 항상 앱을 지속적으로 개선해야합니다. 현재 상황에 만족하고 진화하지 않는 것은 실패의 처방입니다. – F21

+0

그런 다음 질문을 편집하여 1 프레임 크기 비교 비교를 제거하십시오. –

+0

왜 그것이 필요한지 알 수 없습니다. 그것은 내가 스크립트를 테스트하고 내 관찰을 퍼팅 할 때 관찰 한 것이고 각 이미지의 전반적인 변환 시간에 대한 약간의 컨텍스트를 제공합니다. – F21

1

나는 이것들이 조금 늦을 지 모르지만, 여기에 .gif 크기를 조정하는 방법을 찾으려는 사람은 내가 작성한 작은 코드가 이미지에 최대 25 개의 프레임을 유지합니다 (이 코드는 원본 애니메이션 속도를 유지함).

$original = new \Imagick('/path/to/original/image'); 
$new = new \Imagick(); 

$i = 0; 
$frameStep = ceil($original->getNumberImages()/25); 
foreach ($original as $frame) { 
    if ($i % $frameStep === 0) { 
     $delay = $frame->getImageDelay(); 

     $frame->thumbnailImage($x, $y); 
     $frame->setImagePage($x, $y, 0, 0); 
     $frame->setImageDelay($delay * $frameStep); 

     $new->addImage($frame->getImage()); 
    } 

    $i++; 
} 

file_put_contents('/path/to/NEW/file', $new->getImagesBlob()); 

$new->clear(); 
$new->destroy(); 
$original->clear(); 
$original->destroy(); 
관련 문제