문제

무엇이 가장 효율적인 방법으로 크기를 조정하는 큰 이미지를 PHP?

나는 현재 사용하여 GD 기능 imagecopyresampled 높은 해상도의 이미지를 깨끗하게 크기를 조정하기 위해 웹 보기(대략 700 픽셀 700 픽셀 높이).

이 위대한 작품은(2MB)사진과 전체 크기를 조정 작업에 걸리는 두 번째 보다는 더 적은 서버에 있습니다.그러나 이 사이트는 것이 결국 서비스 사진작가할 수 있는 업로드 이미지를 10MB 크기(또는 이미지를 5000x4000 픽셀 크기).

이 종류의 크기를 조정 작업이 큰 이미지로 증가하는 경향이있다 메모리 사용량이 매우 큰 이익률(큰 이미지로 볼 수 있습니다 스파이크 메모리 사용량에 대한 스크립트는 지난 80MB).하는 방법은 없을 만들이의 크기를 조정 작업이 더 효율적입니까?해야 나를 사용하여 다른 이미지와 같은 라이브러리 ImageMagick?

지금 바로,크기 조정 코드는 다음과 같은 형태입니다

function makeThumbnail($sourcefile, $endfile, $thumbwidth, $thumbheight, $quality) {
    // Takes the sourcefile (path/to/image.jpg) and makes a thumbnail from it
    // and places it at endfile (path/to/thumb.jpg).

    // Load image and get image size.
    $img = imagecreatefromjpeg($sourcefile);
    $width = imagesx( $img );
    $height = imagesy( $img );

    if ($width > $height) {
        $newwidth = $thumbwidth;
        $divisor = $width / $thumbwidth;
        $newheight = floor( $height / $divisor);
    } else {
        $newheight = $thumbheight;
        $divisor = $height / $thumbheight;
        $newwidth = floor( $width / $divisor );
    }

    // Create a new temporary image.
    $tmpimg = imagecreatetruecolor( $newwidth, $newheight );

    // Copy and resize old image into new image.
    imagecopyresampled( $tmpimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height );

    // Save thumbnail into a file.
    imagejpeg( $tmpimg, $endfile, $quality);

    // release the memory
    imagedestroy($tmpimg);
    imagedestroy($img);
도움이 되었습니까?

해결책

사람들이 말하는 ImageMagick 은 훨씬 빠릅니다.에서 최고의 라이브러리를 모두 비교하고 측정이다.

  1. 비 1000 일반적인 이미지입니다.
  2. 쓰 두 가지 스크립트를 하나씩 GD,나 에 대한 ImageMagick.
  3. 실행 모두 그들이 몇 번입니다.
  4. 결과를 비교(총 실행 간,CPU 및 I/O 사용법,결과 이미지 품질)입니다.

무언가는,다른 사람 될 수 없습니다 당신을위한 최고입니다.

또한,내 생각,ImageMagick 훨씬 더 나은 인터페이스 API.

다른 팁

여기에서 코드 조각 php.net 문서는 프로젝트에서 사용하고 잘 작동:

<?
function fastimagecopyresampled (&$dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $quality = 3) {
    // Plug-and-Play fastimagecopyresampled function replaces much slower imagecopyresampled.
    // Just include this function and change all "imagecopyresampled" references to "fastimagecopyresampled".
    // Typically from 30 to 60 times faster when reducing high resolution images down to thumbnail size using the default quality setting.
    // Author: Tim Eckel - Date: 09/07/07 - Version: 1.1 - Project: FreeRingers.net - Freely distributable - These comments must remain.
    //
    // Optional "quality" parameter (defaults is 3). Fractional values are allowed, for example 1.5. Must be greater than zero.
    // Between 0 and 1 = Fast, but mosaic results, closer to 0 increases the mosaic effect.
    // 1 = Up to 350 times faster. Poor results, looks very similar to imagecopyresized.
    // 2 = Up to 95 times faster.  Images appear a little sharp, some prefer this over a quality of 3.
    // 3 = Up to 60 times faster.  Will give high quality smooth results very close to imagecopyresampled, just faster.
    // 4 = Up to 25 times faster.  Almost identical to imagecopyresampled for most images.
    // 5 = No speedup. Just uses imagecopyresampled, no advantage over imagecopyresampled.

    if (empty($src_image) || empty($dst_image) || $quality <= 0) { return false; }
    if ($quality < 5 && (($dst_w * $quality) < $src_w || ($dst_h * $quality) < $src_h)) {
        $temp = imagecreatetruecolor ($dst_w * $quality + 1, $dst_h * $quality + 1);
        imagecopyresized ($temp, $src_image, 0, 0, $src_x, $src_y, $dst_w * $quality + 1, $dst_h * $quality + 1, $src_w, $src_h);
        imagecopyresampled ($dst_image, $temp, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $dst_w * $quality, $dst_h * $quality);
        imagedestroy ($temp);
    } else imagecopyresampled ($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
    return true;
}
?>

http://us.php.net/manual/en/function.imagecopyresampled.php#77679

phpThumb 사용 ImageMagick 가능한 속도(다시 떨어지는 GD 필요한 경우)과 같 캐시 꽤 잘 부하를 줄이기 위해 서버에 있습니다.그것은 매우 가볍고 시도하는(이미지 크기를 조정하고,그냥 통화 phpThumb.php 으로 얻는 쿼리를 포함한 그래픽 파일 이름 및 출력 크기),그래서 당신은 수영을 볼 수 당신의 요구 사항을 충족하는 경우.

큰 이미지를 사용하여 표시되어 관심 있는 크기를 조정하는 이미지에 부하 ImageMagick 함으로써 상당히 메모리 사용량을 줄이고 성능을 개선하는 것은 불가능을 가진 GD.

$im = new Imagick();
try {
  $im->pingImage($file_name);
} catch (ImagickException $e) {
  throw new Exception(_('Invalid or corrupted image file, please try uploading another image.'));
}

$width  = $im->getImageWidth();
$height = $im->getImageHeight();
if ($width > $config['width_threshold'] || $height > $config['height_threshold'])
{
  try {
/* send thumbnail parameters to Imagick so that libjpeg can resize images
 * as they are loaded instead of consuming additional resources to pass back
 * to PHP.
 */
    $fitbyWidth = ($config['width_threshold'] / $width) > ($config['height_threshold'] / $height);
    $aspectRatio = $height / $width;
    if ($fitbyWidth) {
      $im->setSize($config['width_threshold'], abs($width * $aspectRatio));
    } else {
      $im->setSize(abs($height / $aspectRatio), $config['height_threshold']);
    }
    $im->readImage($file_name);

/* Imagick::thumbnailImage(fit = true) has a bug that it does fit both dimensions
 */
//  $im->thumbnailImage($config['width_threshold'], $config['height_threshold'], true);

// workaround:
    if ($fitbyWidth) {
      $im->thumbnailImage($config['width_threshold'], 0, false);
    } else {
      $im->thumbnailImage(0, $config['height_threshold'], false);
    }

    $im->setImageFileName($thumbnail_name);
    $im->writeImage();
  }
  catch (ImagickException $e)
  {
    header('HTTP/1.1 500 Internal Server Error');
    throw new Exception(_('An error occured reszing the image.'));
  }
}

/* cleanup Imagick
 */
$im->destroy();

에서 당신은 프로필이 표시되어 관심 있는 사용자,그것은 보인다 당신은 새로운 GD 일부를 공유 이상의 광산, 어쩌면 이것은 비트 떨어져 화제이지만,내가 도움이 될 것이라고 생각하는 새로운 사람이 GD 당신 같은:

1 단계,유효성을 파일입니다. 를 사용하여 다음과 같은 기능을 확인하는 경우 $_FILES['image']['tmp_name'] 파일에 유효 file:

   function getContentsFromImage($image) {
      if (@is_file($image) == true) {
         return file_get_contents($image);
      } else {
         throw new \Exception('Invalid image');
      }
   }
   $contents = getContentsFromImage($_FILES['image']['tmp_name']);

2 단계 얻는 파일 형식 하려고 다음과 같은 기능을 가진 finfo 확장을 확인하는 파일의 파일 형식(콘텐츠).당신은 말할 것 왜 당신은 단지 사용 $_FILES["image"]["type"] 을 확인하는 파일 형식은?기 때문에 그것이 체크인 파일의 확장자는 파일 내용,만약 누군가 이름을 바꾸는 파일 세계입니다.png 하기 world.jpg, $_FILES["image"]["type"] 반지 jpeg,png,그래서 $_FILES["image"]["type"] 반환할 수 있습니다 잘못된 결과입니다.

   function getFormatFromContents($contents) {
      $finfo = new \finfo();
      $mimetype = $finfo->buffer($contents, FILEINFO_MIME_TYPE);
      switch ($mimetype) {
         case 'image/jpeg':
            return 'jpeg';
            break;
         case 'image/png':
            return 'png';
            break;
         case 'image/gif':
            return 'gif';
            break;
         default:
            throw new \Exception('Unknown or unsupported image format');
      }
   }
   $format = getFormatFromContents($contents);

단계입니다.3,을 얻을 GD 자원 을 얻을 GD 자원서 내용 우리가기

   function getGDResourceFromContents($contents) {
      $resource = @imagecreatefromstring($contents);
      if ($resource == false) {
         throw new \Exception('Cannot process image');
      }
      return $resource;
   }
   $resource = getGDResourceFromContents($contents);

4 단계 얻을 차원 이미지 지금 당신은 당신을 얻을 수 있 이미지는 차원이 다음과 같은 간단한 코드:

  $width = imagesx($resource);
  $height = imagesy($resource);

지금 알 변 우리는 원본 이미지 다음:

       $contents, $format, $resource, $width, $height
       OK, lets move on

5 단계,계산한 크기 인수 이미지 이 단계와 관련된 질문의 목적은 다음과 같은 기능을 얻는 것입 크기 조절에 대해 인수 기능 GD imagecopyresampled(), 코드는 좀 오래지만,그것은 좋은 작품을,그것도 세 가지 옵션이 있습니다:스트레칭,축소하고 작성합니다.

:출력 이미지의 차원은 같은 새로운 차원에 당신을 설정합니다.지 않을 높이/폭 비율이 있습니다.

축소:출력 이미지 크기를 초과하지 않습니다 새로운 차원을 제공,그리고 계속 이미지의 높이/폭 비율이 있습니다.

채우기:출력 이미지의 차원은 같으로 새로운 차원을 제공,그것은 것입니다 작물 및 크기 조정 이미지하고,필요할 경우 계속 이미지의 높이/폭 비율이 있습니다. 이 옵션은 무엇을 해야에서 당신의 질문입니다.

   function getResizeArgs($width, $height, $newwidth, $newheight, $option) {
      if ($option === 'stretch') {
         if ($width === $newwidth && $height === $newheight) {
            return false;
         }
         $dst_w = $newwidth;
         $dst_h = $newheight;
         $src_w = $width;
         $src_h = $height;
         $src_x = 0;
         $src_y = 0;
      } else if ($option === 'shrink') {
         if ($width <= $newwidth && $height <= $newheight) {
            return false;
         } else if ($width / $height >= $newwidth / $newheight) {
            $dst_w = $newwidth;
            $dst_h = (int) round(($newwidth * $height) / $width);
         } else {
            $dst_w = (int) round(($newheight * $width) / $height);
            $dst_h = $newheight;
         }
         $src_x = 0;
         $src_y = 0;
         $src_w = $width;
         $src_h = $height;
      } else if ($option === 'fill') {
         if ($width === $newwidth && $height === $newheight) {
            return false;
         }
         if ($width / $height >= $newwidth / $newheight) {
            $src_w = (int) round(($newwidth * $height) / $newheight);
            $src_h = $height;
            $src_x = (int) round(($width - $src_w) / 2);
            $src_y = 0;
         } else {
            $src_w = $width;
            $src_h = (int) round(($width * $newheight) / $newwidth);
            $src_x = 0;
            $src_y = (int) round(($height - $src_h) / 2);
         }
         $dst_w = $newwidth;
         $dst_h = $newheight;
      }
      if ($src_w < 1 || $src_h < 1) {
         throw new \Exception('Image width or height is too small');
      }
      return array(
          'dst_x' => 0,
          'dst_y' => 0,
          'src_x' => $src_x,
          'src_y' => $src_y,
          'dst_w' => $dst_w,
          'dst_h' => $dst_h,
          'src_w' => $src_w,
          'src_h' => $src_h
      );
   }
   $args = getResizeArgs($width, $height, 150, 170, 'fill');

6 단계,이미지 크기 조절$args, $width, $height, $format 과$자원 우리가 위에서 다음과 같은 기능과 새로운 리소스의 이미지 크기 조정:

   function runResize($width, $height, $format, $resource, $args) {
      if ($args === false) {
         return; //if $args equal to false, this means no resize occurs;
      }
      $newimage = imagecreatetruecolor($args['dst_w'], $args['dst_h']);
      if ($format === 'png') {
         imagealphablending($newimage, false);
         imagesavealpha($newimage, true);
         $transparentindex = imagecolorallocatealpha($newimage, 255, 255, 255, 127);
         imagefill($newimage, 0, 0, $transparentindex);
      } else if ($format === 'gif') {
         $transparentindex = imagecolorallocatealpha($newimage, 255, 255, 255, 127);
         imagefill($newimage, 0, 0, $transparentindex);
         imagecolortransparent($newimage, $transparentindex);
      }
      imagecopyresampled($newimage, $resource, $args['dst_x'], $args['dst_y'], $args['src_x'], $args['src_y'], $args['dst_w'], $args['dst_h'], $args['src_w'], $args['src_h']);
      imagedestroy($resource);
      return $newimage;
   }
   $newresource = runResize($width, $height, $format, $resource, $args);

7 단계,새로운 콘텐츠, 다음과 같이 기능을 얻기 내용을 새로운 GD 자원:

   function getContentsFromGDResource($resource, $format) {
      ob_start();
      switch ($format) {
         case 'gif':
            imagegif($resource);
            break;
         case 'jpeg':
            imagejpeg($resource, NULL, 100);
            break;
         case 'png':
            imagepng($resource, NULL, 9);
      }
      $contents = ob_get_contents();
      ob_end_clean();
      return $contents;
   }
   $newcontents = getContentsFromGDResource($newresource, $format);

8 단계 얻을 확장, 다음과 같이 기능의 확장에서 이미지 형식으로(노트,이미지 형식이 동일하지 않 이미지 확장자):

   function getExtensionFromFormat($format) {
      switch ($format) {
         case 'gif':
            return 'gif';
            break;
         case 'jpeg':
            return 'jpg';
            break;
         case 'png':
            return 'png';
      }
   }
   $extension = getExtensionFromFormat($format);

9 단계 이미지 저장 가 있는 경우 사용자 라는 마이크,다음을 수행할 수 있습니다,그것을 저장하여 동일한 폴더로 이 php 스크립트:

$user_name = 'mike';
$filename = $user_name . '.' . $extension;
file_put_contents($filename, $newcontents);

10 단계 파괴하는 리소스 는 것을 잊지 않을 파괴 GD 자원!

imagedestroy($newresource);

거나 쓸 수 있는 모든 코드와 클래스는 단순히 사용하려면 다음을 사용합니다.

   public function __destruct() {
      @imagedestroy($this->resource);
   }

나는 권하지 않을 변환하는 파일 형식으로 사용자는 업로드,당신은 만나 많은 문제입니다.

나는 당신이 작가라

  1. 을 수행 getimagesize()에 업로드된 파일을 확인 이미지 형식 및 크기
  2. 저장 업로드 JPEG 이미지보다 작은 700x700px 에서 대상 폴더에"있는 그대로"
  3. 사용 GD 라이브러리에서 중간 크기의 이미지(이 문서를 참조하세요 위한 샘플 코드: 이미지 크기를 조정하여 PHP 및 GD 라이브러리)
  4. 사용 ImageMagick 에 대한 큰 이미지입니다.당신이 사용할 수 있습 ImageMagick 에서 배경을 선호하는 경우.

사용 ImageMagick 에서 배경,이동 업로드한 파일을 임시 폴더 CRON 작업을 예약하는"변환"의 모든 파일을 jpeg 과 크기를 조정합니다.보 명령문에서는: imagemagick-명령행 처리

당신이라는 메시지를 표시할 수 있습니다 사용자는 파일을 업로드하고 공항 처리해야 합니다.CRON 작업이 될 수 있을 예약 실행에서 매일 특정 간격입니다.소스 이미지의 삭제될 수 있다는 후 처리를 보장하는 이미지를 처리하지 않다.

내가 들어 큰 것에 대해 Imagick 라이브러리,불행하게도 내가 설정에서 내 컴퓨터 작업하고 어느 집에(스트는 시간과 시간을 보냈는 모든 종류의 포럼).

상품,I 을 시도하기로 결정했 이 PHP 클래스:

http://www.verot.net/php_class_upload.htm

그것은 정말 멋진 나는 크기를 조정할 수 있습니다 모든 종류의 이미지(나는 그들을 변환할 수 있습 JPG 도).

ImageMagick 는 다중쓰레드 방식을,그래서 그것이 나타납니다 더 빨리,하지만 실제로 많이 사용하는 것보다 많은 리소스 GD.실행 한 경우 여러 PHP 스크립트에서 병렬을 사용하여 모든 GD 다음 그들이 이길 ImageMagick 에서 속도를 위해 간단한 작업입니다.ExactImage 는보다 강력 ImageMagick 하지만 훨씬 더 빨리,하지만 사용할 수 없습을 통해 PHP,당신은 그것을 설치하는 서버에서 실행을 통해 exec.

큰 이미지를 사용 phpThumb().여기를 사용하는 방법입니다: http://abcoder.com/php/problem-with-resizing-corrupted-images-using-php-image-functions/.그것은 또한 작품에 대한 큰 손상된 이미지입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top