문제
무엇이 가장 효율적인 방법으로 크기를 조정하는 큰 이미지를 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 은 훨씬 빠릅니다.에서 최고의 라이브러리를 모두 비교하고 측정이다.
- 비 1000 일반적인 이미지입니다.
- 쓰 두 가지 스크립트를 하나씩 GD,나 에 대한 ImageMagick.
- 실행 모두 그들이 몇 번입니다.
- 결과를 비교(총 실행 간,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);
}
팁
나는 권하지 않을 변환하는 파일 형식으로 사용자는 업로드,당신은 만나 많은 문제입니다.
나는 당신이 작가라
- 을 수행 getimagesize()에 업로드된 파일을 확인 이미지 형식 및 크기
- 저장 업로드 JPEG 이미지보다 작은 700x700px 에서 대상 폴더에"있는 그대로"
- 사용 GD 라이브러리에서 중간 크기의 이미지(이 문서를 참조하세요 위한 샘플 코드: 이미지 크기를 조정하여 PHP 및 GD 라이브러리)
- 사용 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/.그것은 또한 작품에 대한 큰 손상된 이미지입니다.