PHP Conference Japan 2024

imagecopyresampled

(PHP 4 >= 4.0.6,PHP 5,PHP 7,PHP 8)

imagecopyresampled複製並調整影像部分的大小,並重新取樣

描述

imagecopyresampled(
    GdImage $dst_image,
    GdImage $src_image,
    int $dst_x,
    int $dst_y,
    int $src_x,
    int $src_y,
    int $dst_width,
    int $dst_height,
    int $src_width,
    int $src_height
): bool

imagecopyresampled() 會將一個影像的矩形部分複製到另一個影像,平滑地內插像素值,因此,尤其是在縮小影像尺寸時,仍能保留很大的清晰度。

換句話說,imagecopyresampled() 會從 src_image 中取出寬度為 src_width、高度為 src_height,位置在 (src_x, src_y) 的矩形區域,並將其放置在 dst_image 中寬度為 dst_width、高度為 dst_height,位置在 (dst_x, dst_y) 的矩形區域。

如果來源和目標的坐標以及寬度和高度不同,則將執行影像片段的適當拉伸或縮小。坐標指的是左上角。此函數可以用於複製同一個影像內的區域(如果 dst_imagesrc_image 相同),但如果區域重疊,則結果將無法預測。

參數

dst_image

目標影像資源。

src_image

來源影像資源。

dst_x

目標點的 x 座標。

dst_y

目標點的 y 座標。

src_x

來源點的 x 座標。

src_y

來源點的 y 座標。

dst_width

目標寬度。

dst_height

目標高度。

src_width

來源寬度。

src_height

來源高度。

回傳值

成功時回傳 true,失敗時回傳 false

變更日誌

版本 描述
8.0.0 dst_imagesrc_image 現在預期 GdImage 實例;先前預期的是 resource

範例

範例 #1 簡單範例

此範例會將影像重新取樣為其原始大小的一半。

<?php
// 檔案
$filename = 'test.jpg';
$percent = 0.5;

// 內容類型
header('Content-Type: image/jpeg');

// 取得新的尺寸
list($width, $height) = getimagesize($filename);
$new_width = $width * $percent;
$new_height = $height * $percent;

// 重新取樣
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

// 輸出
imagejpeg($image_p, null, 100);
?>

以上範例將輸出類似如下的內容

Output of example : Simple example

範例 #2 按比例重新取樣影像

此範例將顯示最大寬度或高度為 200 像素的影像。

<?php
// 檔案
$filename = 'test.jpg';

// 設定最大寬度和高度
$width = 200;
$height = 200;

// 內容類型
header('Content-Type: image/jpeg');

// 取得新的尺寸
list($width_orig, $height_orig) = getimagesize($filename);

$ratio_orig = $width_orig/$height_orig;

if (
$width/$height > $ratio_orig) {
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}

// 重新取樣
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

// 輸出
imagejpeg($image_p, null, 100);
?>

以上範例將輸出類似如下的內容

Output of example : Resampling an image proportionally

注意事項

注意:

由於調色盤影像的限制(255+1 種顏色),會產生問題。重新取樣或過濾影像通常需要超過 255 種顏色,因此會使用近似值來計算新的重新取樣像素及其顏色。對於調色盤影像,我們嘗試分配新的顏色,如果失敗,則會選擇(理論上)最接近的計算顏色。這並不總是視覺上最接近的顏色。這可能會產生奇怪的結果,例如空白(或視覺上空白)的影像。為了跳過這個問題,請使用真彩色影像作為目標影像,例如使用 imagecreatetruecolor() 建立的影像。

參見

新增註解

使用者貢獻的註解 37 則註解

wbcarts at juno dot com
11 年前
四個矩形

$src_image $dst_image
+------------+---------------------------------+ +------------+--------------------+
| | | | | |
| | | | $dst_y |
| | | | | |
| $src_y | +-- $dst_x --+----$dst_width----+ |
| | | | | | |
| | | | | 重新取樣 | |
| | | | | | |
+-- $src_x --+------ $src_width ------+ | | $dst_height | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | +------------------+ |
| | 取樣 | | | |
| | | | | |
| | | | | |
| $src_height | | | |
| | | | +---------------------------------+
| | | |
| | | |
| +------------------------+ |
| |
| |
+----------------------------------------------+
promaty at gmail dot com
13 年前
這是我的終極影像調整大小工具,它保留了 GIF 和 PNG 的透明度,並具有將影像裁剪為固定尺寸的選項(預設情況下保留影像比例)

<?php
function image_resize($src, $dst, $width, $height, $crop=0){

if(!list(
$w, $h) = getimagesize($src)) return "不支援的圖片類型!";

$type = strtolower(substr(strrchr($src,"."),1));
if(
$type == 'jpeg') $type = 'jpg';
switch(
$type){
case
'bmp': $img = imagecreatefromwbmp($src); break;
case
'gif': $img = imagecreatefromgif($src); break;
case
'jpg': $img = imagecreatefromjpeg($src); break;
case
'png': $img = imagecreatefrompng($src); break;
default : return
"不支援的圖片類型!";
}

// 調整大小
if($crop){
if(
$w < $width or $h < $height) return "圖片太小!";
$ratio = max($width/$w, $height/$h);
$h = $height / $ratio;
$x = ($w - $width / $ratio) / 2;
$w = $width / $ratio;
}
else{
if(
$w < $width and $h < $height) return "圖片太小!";
$ratio = min($width/$w, $height/$h);
$width = $w * $ratio;
$height = $h * $ratio;
$x = 0;
}

$new = imagecreatetruecolor($width, $height);

// 保留透明度
if($type == "gif" or $type == "png"){
imagecolortransparent($new, imagecolorallocatealpha($new, 0, 0, 0, 127));
imagealphablending($new, false);
imagesavealpha($new, true);
}

imagecopyresampled($new, $img, 0, 0, $x, 0, $width, $height, $w, $h);

switch(
$type){
case
'bmp': imagewbmp($new, $dst); break;
case
'gif': imagegif($new, $dst); break;
case
'jpg': imagejpeg($new, $dst); break;
case
'png': imagepng($new, $dst); break;
}
return
true;
}
?>

我將新影像上傳到伺服器時使用的範例。

這會將原始圖片以以下形式儲存
original.type

並建立新的縮圖
100x100.type

<?php
$pic_type
= strtolower(strrchr($picture['name'],"."));
$pic_name = "original$pic_type";
move_uploaded_file($picture['tmp_name'], $pic_name);
if (
true !== ($pic_error = @image_resize($pic_name, "100x100$pic_type", 100, 100, 1))) {
echo
$pic_error;
unlink($pic_name);
}
else echo
"OK!";
?>

乾杯!
zorroswordsman at gmail dot com
16 年前
我建立了一個 PHP5 圖片調整大小的類別,使用 ImageCopyResampled,可能對某些人有用,它支援 JPEG、PNG 和 GIF 格式。調整大小時會保留原始圖片的長寬比,如果原始寬度和高度小於所需的調整大小,則不會調整大小或重新取樣。

<?php

// Imaging
class imaging
{

// Variables
private $img_input;
private
$img_output;
private
$img_src;
private
$format;
private
$quality = 80;
private
$x_input;
private
$y_input;
private
$x_output;
private
$y_output;
private
$resize;

// Set image
public function set_img($img)
{

// Find format
$ext = strtoupper(pathinfo($img, PATHINFO_EXTENSION));

// JPEG image
if(is_file($img) && ($ext == "JPG" OR $ext == "JPEG"))
{

$this->format = $ext;
$this->img_input = ImageCreateFromJPEG($img);
$this->img_src = $img;


}

// PNG image
elseif(is_file($img) && $ext == "PNG")
{

$this->format = $ext;
$this->img_input = ImageCreateFromPNG($img);
$this->img_src = $img;

}

// GIF image
elseif(is_file($img) && $ext == "GIF")
{

$this->format = $ext;
$this->img_input = ImageCreateFromGIF($img);
$this->img_src = $img;

}

// Get dimensions
$this->x_input = imagesx($this->img_input);
$this->y_input = imagesy($this->img_input);

}

// Set maximum image size (pixels)
public function set_size($size = 100)
{

// Resize
if($this->x_input > $size && $this->y_input > $size)
{

// Wide
if($this->x_input >= $this->y_input)
{

$this->x_output = $size;
$this->y_output = ($this->x_output / $this->x_input) * $this->y_input;

}

// Tall
else
{

$this->y_output = $size;
$this->x_output = ($this->y_output / $this->y_input) * $this->x_input;

}

// Ready
$this->resize = TRUE;

}

// Don't resize
else { $this->resize = FALSE; }

}

// Set image quality (JPEG only)
public function set_quality($quality)
{

if(
is_int($quality))
{

$this->quality = $quality;

}

}

// Save image
public function save_img($path)
{

// Resize
if($this->resize)
{

$this->img_output = ImageCreateTrueColor($this->x_output, $this->y_output);
ImageCopyResampled($this->img_output, $this->img_input, 0, 0, 0, 0, $this->x_output, $this->y_output, $this->x_input, $this->y_input);

}

// Save JPEG
if($this->format == "JPG" OR $this->format == "JPEG")
{

if(
$this->resize) { imageJPEG($this->img_output, $path, $this->quality); }
else {
copy($this->img_src, $path); }

}

// Save PNG
elseif($this->format == "PNG")
{

if(
$this->resize) { imagePNG($this->img_output, $path); }
else {
copy($this->img_src, $path); }

}

// Save GIF
elseif($this->format == "GIF")
{

if(
$this->resize) { imageGIF($this->img_output, $path); }
else {
copy($this->img_src, $path); }

}

}

// Get width
public function get_width()
{

return
$this->x_input;

}

// Get height
public function get_height()
{

return
$this->y_input;

}

// Clear image cache
public function clear_cache()
{

@
ImageDestroy($this->img_input);
@
ImageDestroy($this->img_output);

}

}

##### DEMO #####

// Image
$src = "myimage.jpg";

// Begin
$img = new imaging;
$img->set_img($src);
$img->set_quality(80);

// Small thumbnail
$img->set_size(200);
$img->save_img("small_" . $src);

// Baby thumbnail
$img->set_size(50);
$img->save_img("baby_" . $src);

// Finalize
$img->clear_cache();

?>
wm at violet dot bg
16 年前
這是 liviu.malaescu 發佈的 ImageCopyResampledBicubic 的修正版本
原始版本沒有尊重 src_x 和 src_y 參數

<?php
function ImageCopyResampledBicubic(&$dst_image, &$src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
// 我們應該首先從來源中剪下我們感興趣的部分
$src_img = ImageCreateTrueColor($src_w, $src_h);
imagecopy($src_img, $src_image, 0, 0, $src_x, $src_y, $src_w, $src_h);

// 這個用作臨時圖片
$dst_img = ImageCreateTrueColor($dst_w, $dst_h);

ImagePaletteCopy($dst_img, $src_img);
$rX = $src_w / $dst_w;
$rY = $src_h / $dst_h;
$w = 0;
for (
$y = 0; $y < $dst_h; $y++) {
$ow = $w; $w = round(($y + 1) * $rY);
$t = 0;
for (
$x = 0; $x < $dst_w; $x++) {
$r = $g = $b = 0; $a = 0;
$ot = $t; $t = round(($x + 1) * $rX);
for (
$u = 0; $u < ($w - $ow); $u++) {
for (
$p = 0; $p < ($t - $ot); $p++) {
$c = ImageColorsForIndex($src_img, ImageColorAt($src_img, $ot + $p, $ow + $u));
$r += $c['red'];
$g += $c['green'];
$b += $c['blue'];
$a++;
}
}
ImageSetPixel($dst_img, $x, $y, ImageColorClosest($dst_img, $r / $a, $g / $a, $b / $a));
}
}

// 將臨時圖片套用在返回的圖片上,並使用目標 x,y 座標
imagecopy($dst_image, $dst_img, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h);

// 我們應該返回 true,因為 ImageCopyResampled/ImageCopyResized 也是這樣做的
return true;
}
?>
mattura gmail com
16 年前
這是我寫的一個小函數,可以將圖片調整為最大尺寸 - 基於 facebook 在相簿中的做法。您輸入來源、目標和最大尺寸(以像素為單位,例如 300),例如,如果圖片又長又細,則最長邊將為 300 像素,但圖片會保留比例。正方形圖片將變成 300x300,6x4(橫向)將變成 300x200,4x6(直向)- 200x300 等。
它適用於 jpg 圖片,但可以輕鬆添加其他格式。
<?php
function createThumb($spath, $dpath, $maxd) {
$src=@imagecreatefromjpeg($spath);
if (!
$src) {return false;} else {
$srcw=imagesx($src);
$srch=imagesy($src);
if (
$srcw<$srch) {$height=$maxd;$width=floor($srcw*$height/$srch);}
else {
$width=$maxd;$height=floor($srch*$width/$srcw);}
if (
$width>$srcw && $height>$srch) {$width=$srcw;$height=$srch;} // 如果圖片實際上比您想要的還小,則保留小尺寸(移除此行以進行調整大小)
$thumb=imagecreatetruecolor($width, $height);
if (
$height<100) {imagecopyresized($thumb, $src, 0, 0, 0, 0, $width, $height, imagesx($src), imagesy($src));}
else {
imagecopyresampled($thumb, $src, 0, 0, 0, 0, $width, $height, imagesx($src), imagesy($src));}
imagejpeg($thumb, $dpath);
return
true;
}
}
?>
Dave McCourt
17 年前
這個函式取自許多網路資源,感謝所有發文者。它可以從直式或橫式的原始圖片中,建立正方形或橫式的 .jpg 縮圖。我事先決定縮圖的顯示方式,以保持一致性。我通常會在上傳後銳化圖片,以節省伺服器資源。如果有人需要,我可以提供這段程式碼。希望對大家有所幫助...

# 從 jpg 建立縮圖
# 用法
# create_jpgthumb(上傳的檔案, 最後的檔案(含路徑), 縮圖高度, 縮圖寬度, jpg 品質, 縮放縮圖 (true) 或固定大小 (false) );
function create_jpgthumb($original, $thumbnail, $max_width, $max_height, $quality, $scale = true) {

list ($src_width, $src_height, $type, $w) = getimagesize($original);

if (!$srcImage = @imagecreatefromjpeg($original)) {
return false;
}

# 圖片調整為自然高度和寬度
if ($scale == true) {

if ($src_width > $src_height ) {
$thumb_width = $max_width;
$thumb_height = floor($src_height * ($max_width / $src_width));
} else if ($src_width < $src_height ) {
$thumb_height = $max_height;
$thumb_width = floor($src_width * ($max_height / $src_height));
} else {
$thumb_width = $max_height;
$thumb_height = $max_height;
}

if (!@$destImage = imagecreatetruecolor($thumb_width, $thumb_height)) {
return false;
}

if (!@imagecopyresampled($destImage, $srcImage, 0, 0, 0, 0, $thumb_width, $thumb_height, $src_width, $src_height)) {
return false;
}

# 圖片固定為指定寬度和高度並裁剪
} else if ($scale == false) {

$ratio = $max_width / $max_height;

# 縮圖為橫式
if ($ratio > 1) {

# 上傳的圖片為橫式
if ($src_width > $src_height) {

$thumb_width = $max_width;
$thumb_height = ceil($max_width * ($src_height / $src_width));

if ($thumb_height > $max_width) {
$thumb_height = $max_width;
$thumb_width = ceil($max_width * ($src_width / $src_height));
}

# 上傳的圖片為直式
} else {

$thumb_height = $max_width;
$thumb_width = ceil($max_width * ($src_height / $src_width));

if ($thumb_width > $max_width) {
$thumb_width = $max_width;
$thumb_height = ceil($max_width * ($src_height / $src_width));
}

$off_h = ($src_height - $src_width) / 2;

}

if (!@$destImage = imagecreatetruecolor($max_width, $max_height)) {
return false;
}

if (!@imagecopyresampled($destImage, $srcImage, 0, 0, 0, $off_h, $thumb_width, $thumb_height, $src_width, $src_height)) {
return false;
}

# 縮圖為正方形
} else {

if ($src_width > $src_height) {
$off_w = ($src_width - $src_height) / 2;
$off_h = 0;
$src_width = $src_height;
} else if ($src_height > $src_width) {
$off_w = 0;
$off_h = ($src_height - $src_width) / 2;
$src_height = $src_width;
} else {
$off_w = 0;
$off_h = 0;
}

if (!@$destImage = imagecreatetruecolor($max_width, $max_height)) {
return false;
}

if (!@imagecopyresampled($destImage, $srcImage, 0, 0, $off_w, $off_h, $max_width, $max_height, $src_width, $src_height)) {
return false;
}

}


}

@imagedestroy($srcImage);

if (!@imageantialias($destImage, true)) {
return false;
}

if (!@imagejpeg($destImage, $thumbnail, $quality)) {
return false;
}

@imagedestroy($destImage);

return true;
}
kazuya
10 年前
<?php

$new_file
= img_resize("./img/", "test.jpg","copy_test.jpg",300);
echo
"<IMG src = '$new_file'>";

function
img_resize($path,$tmp_name,$new_name,$new_width){
if (!
file_exists($path.$filename)){
echo
"file not found!";
exit;
}
if (!
is_writable($path)){
echo
"error:permission denied!";
exit;
}
list(
$width, $height) = getimagesize($path . $tmp_name);
$new_height = abs($new_width * $height / $width);
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($path . $tmp_name);
imagecopyresampled($image_p, $image, 0, 0, 0, 0,
$new_width, $new_height, $width, $height);
imagejpeg($image_p, $path . $new_name);
return
$path.$new_name;
}

?>
Anonymous
19 年前
應該注意的是,imagecopyresampled() 函式比 Photoshop CS 的預設雙立方函式模糊得多,看起來類似於 Photoshop 雙線性函式的模糊版本。文件沒有註明重採樣使用了哪種演算法。
z3n666 at gmail dot com
15 年前
我到處尋找,但找不到一個可以將圖片調整為任何比例而不留下空白區域的函式,所以我寫了這個。它能夠將圖片調整為任何大小比例,當比例與原始圖片不符時,它會在原始圖片上裁剪成比例的區域並調整大小。

<?php

function _ckdir($fn) {
if (
strpos($fn,"/") !== false) {
$p=substr($fn,0,strrpos($fn,"/"));
if (!
is_dir($p)) {
_o("Mkdir: ".$p);
mkdir($p,777,true);
}
}
}
function
img_resizer($src,$quality,$w,$h,$saveas) {
/* v2.5 with auto crop */
$r=1;
$e=strtolower(substr($src,strrpos($src,".")+1,3));
if ((
$e == "jpg") || ($e == "peg")) {
$OldImage=ImageCreateFromJpeg($src) or $r=0;
} elseif (
$e == "gif") {
$OldImage=ImageCreateFromGif($src) or $r=0;
} elseif (
$e == "bmp") {
$OldImage=ImageCreateFromwbmp($src) or $r=0;
} elseif (
$e == "png") {
$OldImage=ImageCreateFromPng($src) or $r=0;
} else {
_o("Not a Valid Image! (".$e.") -- ".$src);$r=0;
}
if (
$r) {
list(
$width,$height)=getimagesize($src);
// check if ratios match
$_ratio=array($width/$height,$w/$h);
if (
$_ratio[0] != $_ratio[1]) { // crop image

// find the right scale to use
$_scale=min((float)($width/$w),(float)($height/$h));

// coords to crop
$cropX=(float)($width-($_scale*$w));
$cropY=(float)($height-($_scale*$h));

// cropped image size
$cropW=(float)($width-$cropX);
$cropH=(float)($height-$cropY);

$crop=ImageCreateTrueColor($cropW,$cropH);
// crop the middle part of the image to fit proportions
ImageCopy(
$crop,
$OldImage,
0,
0,
(int)(
$cropX/2),
(int)(
$cropY/2),
$cropW,
$cropH
);
}

// do the thumbnail
$NewThumb=ImageCreateTrueColor($w,$h);
if (isset(
$crop)) { // been cropped
ImageCopyResampled(
$NewThumb,
$crop,
0,
0,
0,
0,
$w,
$h,
$cropW,
$cropH
);
ImageDestroy($crop);
} else {
// ratio match, regular resize
ImageCopyResampled(
$NewThumb,
$OldImage,
0,
0,
0,
0,
$w,
$h,
$width,
$height
);
}
_ckdir($saveas);
ImageJpeg($NewThumb,$saveas,$quality);
ImageDestroy($NewThumb);
ImageDestroy($OldImage);
}
return
$r;
}

?>
satanas147 at gmail dot com
15 年前
這是先前用於縮圖的 php5 類別的另一個附加功能(合併了 Matt 和 Zorro 的建議)。
這個程式碼專門用於在使用縮圖子類別的網頁上動態產生縮圖。
它將產生的縮圖儲存在同一個目錄中,檔名為 myimage_tn。
我使用 php5 的經驗還很淺,所以我認為這可以最佳化,但目前看起來運作良好。

<?php
// Imaging
class imaging
{
// Variables
private $img_input;
private
$img_output;
private
$img_src;
private
$format;
private
$quality = 80;
private
$x_input;
private
$y_input;
private
$x_output;
private
$y_output;
private
$resize;

// Set image
public function set_img($img)
{
// Find format
$ext = strtoupper(pathinfo($img, PATHINFO_EXTENSION));
// JPEG image
if(is_file($img) && ($ext == "JPG" OR $ext == "JPEG"))
{
$this->format = $ext;
$this->img_input = ImageCreateFromJPEG($img);
$this->img_src = $img;
}
// PNG image
elseif(is_file($img) && $ext == "PNG")
{
$this->format = $ext;
$this->img_input = ImageCreateFromPNG($img);
$this->img_src = $img;
}
// GIF image
elseif(is_file($img) && $ext == "GIF")
{
$this->format = $ext;
$this->img_input = ImageCreateFromGIF($img);
$this->img_src = $img;
}
// Get dimensions
$this->x_input = imagesx($this->img_input);
$this->y_input = imagesy($this->img_input);
}

// Set maximum image size (pixels)
public function set_size($max_x = 100,$max_y = 100)
{
// Resize
if($this->x_input > $max_x || $this->y_input > $max_y)
{
$a= $max_x / $max_y;
$b= $this->x_input / $this->y_input;
if (
$a<$b)
{
$this->x_output = $max_x;
$this->y_output = ($max_x / $this->x_input) * $this->y_input;
}
else
{
$this->y_output = $max_y;
$this->x_output = ($max_y / $this->y_input) * $this->x_input;
}
// Ready
$this->resize = TRUE;
}
// Don't resize
else { $this->resize = FALSE; }
}
// Set image quality (JPEG only)
public function set_quality($quality)
{
if(
is_int($quality))
{
$this->quality = $quality;
}
}
// Save image
public function save_img($path)
{
// Resize
if($this->resize)
{
$this->img_output = ImageCreateTrueColor($this->x_output, $this->y_output);
ImageCopyResampled($this->img_output, $this->img_input, 0, 0, 0, 0, $this->x_output, $this->y_output, $this->x_input, $this->y_input);
}
// Save JPEG
if($this->format == "JPG" OR $this->format == "JPEG")
{
if(
$this->resize) { imageJPEG($this->img_output, $path, $this->quality); }
else {
copy($this->img_src, $path); }
}
// Save PNG
elseif($this->format == "PNG")
{
if(
$this->resize) { imagePNG($this->img_output, $path); }
else {
copy($this->img_src, $path); }
}
// Save GIF
elseif($this->format == "GIF")
{
if(
$this->resize) { imageGIF($this->img_output, $path); }
else {
copy($this->img_src, $path); }
}
}
// Get width
public function get_width()
{
return
$this->x_input;
}
// Get height
public function get_height()
{
return
$this->y_input;
}
// Clear image cache
public function clear_cache()
{
@
ImageDestroy($this->img_input);
@
ImageDestroy($this->img_output);
}
}
class
thumbnail extends imaging {
private
$image;
private
$width;
private
$height;

function
__construct($image,$width,$height) {
parent::set_img($image);
parent::set_quality(80);
parent::set_size($width,$height);
$this->thumbnail= pathinfo($image, PATHINFO_DIRNAME).pathinfo($image, PATHINFO_FILENAME).'_tn.'.pathinfo($image, PATHINFO_EXTENSION);
parent::save_img($this->thumbnail);
parent::clear_cache();
}
function
__toString() {
return
$this->thumbnail;
}
}

********
*
DEMO *
********
$thumb = new thumbnail('./image_dir/sub_dir/myimage.jpg',100,100);
echo
'<img src=\''.$thumb.'\' alt=\'myimage\' title=\'myimage\'/>';

?>
julien at go-on-web dot com
10 年前
Windows 不接受浮點數的寬度和高度...

因此,在「範例 #2 按比例重新取樣影像」中,請優先使用
<?php
if ($width/$height > $ratio_orig) {
$width = round( $height*$ratio_orig );
} else {
$height = round( $width/$ratio_orig );
}
?>
(使用了 "round")
否則您的圖片將不會調整大小。
bobbyboyojones at hotmail dot com
16 年前
我討厭放大圖片時產生巨大的像素而不是更平滑的外觀,所以我寫了這個函式。它需要更長的時間,但會產生更好的效果。

<?php

function imagecopyresampledSMOOTH(&$dst_img, &$src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $mult=1.25){
// 不要使用太接近整數的 $mult 值,否則此函數效果不明顯

$tgt_w = round($src_w * $mult);
$tgt_h = round($src_h * $mult);

// 使用 $mult <= 1 會使目前的步驟 w/h 變小(或相同),不允許這樣,總是至少調整一個像素大小
if($tgt_w <= $src_w){ $tgt_w += 1; }
if(
$tgt_h <= $src_h){ $tgt_h += 1; }

// 如果目前步驟的 w/h 大於最終高度,則將其調整回最終大小
// 此檢查也使得如果我們正在縮小圖像尺寸,它會一步到位(因為那已經很平滑了)
if($tgt_w > $dst_w){ $tgt_w = $dst_w; }
if(
$tgt_h > $dst_h){ $tgt_h = $dst_h; }

$tmpImg = imagecreatetruecolor($tgt_w, $tgt_h);

imagecopyresampled($tmpImg, $src_img, 0, 0, $src_x, $src_y, $tgt_w, $tgt_h, $src_w, $src_h);
imagecopy($dst_img, $tmpImg, $dst_x, $dst_y, 0, 0, $tgt_w, $tgt_h);
imagedestroy($tmpImg);

// 只要尚未達到最終 w/h,就繼續調整大小
if($tgt_w < $dst_w OR $tgt_h < $dst_h){
imagecopyresampledSMOOTH($dst_img, $dst_img, $dst_x, $dst_y, $dst_x, $dst_y, $dst_w, $dst_h, $tgt_w, $tgt_h, $mult);
}
}

?>
tim dot daldini at gmail dot be
17 年前
Tim 的函數速度快很多,然而,品質設定似乎不太正確,因為調整非常大的影像尺寸時,例如品質 1 的設定,對於產生的縮圖品質影響不大。

有人知道如何透過比較影像表面(例如)來根據 Tim 的函數使用更正確的品質設定嗎?

總共 10 百萬像素的影像,在調整大小後包含 5 百萬像素時,應該使用與包含 1 百萬像素但調整大小後僅包含 0.5 百萬像素的影像相同的品質設定。

不難理解,但如果函數可以自動決定在將大型影像調整為小型縮圖時使用品質 1 的設定,則記憶體負載會低得多。當在同一個應用程式中使用不同大小的影像時,這會特別方便。
seifer at loveletslive dot com
15 年前
好的,我看到其他人已經發布過了,但我只是隨便弄了一下並把它做出來,所以我想分享一下。

我的程式碼可以運作,並不是說其他人的程式碼不能運作,我沒有測試過它們。

此函數會建立指定大小的縮圖。
如果縮圖的比例不同,它將會自動裁剪來源影像的中心。

如果來源影像大於或小於所需的「裁剪縮圖」,它都可以運作。

以下是程式碼...
<?php
function CroppedThumbnail($imgSrc,$thumbnail_width,$thumbnail_height) { //$imgSrc 是一個檔案 - 傳回一個影像資源。
// 取得影像的尺寸
list($width_orig, $height_orig) = getimagesize($imgSrc);
$myImage = imagecreatefromjpeg($imgSrc);
$ratio_orig = $width_orig/$height_orig;

if (
$thumbnail_width/$thumbnail_height > $ratio_orig) {
$new_height = $thumbnail_width/$ratio_orig;
$new_width = $thumbnail_width;
} else {
$new_width = $thumbnail_height*$ratio_orig;
$new_height = $thumbnail_height;
}

$x_mid = $new_width/2; // 水平中間
$y_mid = $new_height/2; // 垂直中間

$process = imagecreatetruecolor(round($new_width), round($new_height));

imagecopyresampled($process, $myImage, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
$thumb = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
imagecopyresampled($thumb, $process, 0, 0, ($x_mid-($thumbnail_width/2)), ($y_mid-($thumbnail_height/2)), $thumbnail_width, $thumbnail_height, $thumbnail_width, $thumbnail_height);

imagedestroy($process);
imagedestroy($myImage);
return
$thumb;
}

// 建立縮圖
$newThumb = CroppedThumbnail("MyImageName.jpg",75,100);

// 並顯示影像...
header('Content-type: image/jpeg');
imagejpeg($newThumb);
?>
alex-thennstaett-remove at gmx dot net
12 年前
將 GD 函式庫從 2.0.35-r1 更新到 2.0.35-r3 後,使用 $dstX 或 $dstY 的負數開始產生無法預測的結果,例如插入縮小的影像並自行放大 $dstH 或 $dstW。雖然它之前運作良好,但從一開始就應該避免使用或計算 imagecopyresampled 的負數。
mark at manngo dot net
2 年前
請注意,在 PHP 8.1 中,如果參數是浮點數,您會收到過時的錯誤。如果您轉換參數,您將會省去很多煩惱

<?php
imagecopyresampled
(
$dst_image, $src_image,
(int)
$dst_x, (int) $dst_y,
(int)
$src_x, (int) $src_y,
(int)
$dst_width, (int) $dst_height,
(int)
$src_width, (int) $src_height
);
?>

你也可以將它們四捨五入,但我認為將它們轉換為整數更符合原始行為。
sam at durosoft.com
11 年前
終極智慧型影像調整大小常式。您提供原始影像,以及期望的寬度和/或高度。此函數會智慧地調整原始影像大小,使其置中符合指定的尺寸。可以省略寬度或高度,使調整大小僅「鎖定」寬度或高度。非常適合用於產生縮圖。設計用於處理 PNG 檔案。

function resize_image_smart($orig, $dest_width=null, $dest_height=null)
{
$orig_width = imagesx($orig);
$orig_height = imagesy($orig);
$vertical_offset = 0;
$horizontal_offset = 0;
if($dest_width == null)
{
if($dest_height == null)
{
die('$dest_width 和 $dest_height 不能都為 null!');
}
// 高度鎖定
$dest_width = $dest_height * $orig_width / $orig_height;
} else {
if($dest_height == null)
{
// 寬度鎖定
$dest_height = $dest_width * $orig_height / $orig_width;
} else {
// 兩個尺寸都鎖定
$vertical_offset = $dest_height - ($orig_height * $dest_width) / $orig_width;
$horizontal_offset = $dest_width - ($dest_height * $orig_width) / $orig_height;
if($vertical_offset < 0) $vertical_offset = 0;
if($horizontal_offset < 0) $horizontal_offset = 0;
}
}
$img = imagecreatetruecolor($dest_width, $dest_height);
imagesavealpha($img, true);
imagealphablending($img, false);
$transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $transparent);
imagecopyresampled($img, $orig, round($horizontal_offset / 2),
round($vertical_offset / 2),
0,
0,
round($dest_width - $horizontal_offset),
round($dest_height - $vertical_offset),
$orig_width,
$orig_height);
return $img;
}
guru_boy87 at hotmail dot com
14 年前
調整影像大小的函數。

<?php
function resizeImage($originalImage,$toWidth,$toHeight)
{

list(
$width, $height) = getimagesize($originalImage);
$xscale=$width/$toWidth;
$yscale=$height/$toHeight;

if (
$yscale>$xscale){
$new_width = round($width * (1/$yscale));
$new_height = round($height * (1/$yscale));
}
else {
$new_width = round($width * (1/$xscale));
$new_height = round($height * (1/$xscale));
}


$imageResized = imagecreatetruecolor($new_width, $new_height);
$imageTmp = imagecreatefromjpeg ($originalImage);
imagecopyresampled($imageResized, $imageTmp, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

return
$imageResized;


}
?>
zuegs
15 年前
重新取樣 GIF 並保留透明度並不總是有效,因為取樣因子會使產生的重新取樣影像有一些雜訊,導致「imagegif」無法找到所有透明像素。
修正此問題的一種方法是將所有具有高 alpha 值的像素重設為完全透明。
<?php
// 載入/建立影像
$img_src=imagecreatefromgif($g_srcfile);
$img_dst=imagecreatetruecolor($g_iw,$g_ih);
imagealphablending($img_dst, false);

// 取得並重新配置透明顏色
$transindex = imagecolortransparent($img_src);
if(
$transindex >= 0) {
$transcol = imagecolorsforindex($img_src, $transindex);
$transindex = imagecolorallocatealpha($img_dst, $transcol['red'], $transcol['green'], $transcol['blue'], 127);
imagefill($img_dst, 0, 0, $transindex);
}

// 重新取樣
imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $g_iw, $g_ih, $g_is[0], $g_is[1]);

// 還原透明度
if($transindex >= 0) {
imagecolortransparent($img_dst, $transindex);
for(
$y=0; $y<$g_ih; ++$y)
for(
$x=0; $x<$g_iw; ++$x)
if(((
imagecolorat($img_dst, $x, $y)>>24) & 0x7F) >= 100) imagesetpixel($img_dst, $x, $y, $transindex);

// 儲存 GIF
imagetruecolortopalette($img_dst, true, 255);
imagesavealpha($img_dst, false);
imagegif($img_dst, $g_dstfile);
imagedestroy($img_dst);
?>
Warren
15 年前
這是我為了製作縮圖而編寫的函數 - 它會接受來源*影像資源*和目的地*路徑*,以及最大尺寸和縮圖是否應該是正方形。

我選擇接受資源作為來源,以便更有效率地建立多種大小。例如

<?php
$src_im
=@imagecreatefromjpeg($pathtofile);
$large = resize($src_im,$destination_large,1024);
@
imagedestroy($src_im);
$medium = resize($large,$destination_medium,500);
@
imagedestroy($large);
$small = resize($medium,$destination_small,125);
@
imagedestroy($medium);
$square = resize($small,$destination_square,75,TRUE);
@
imagedestroy($small);
@
imagedestroy($square);

function
resize($src_im, $dpath, $maxd, $square=false) {
$src_width = imagesx($src_im);
$src_height = imagesy($src_im);
$src_w=$src_width;
$src_h=$src_height;
$src_x=0;
$src_y=0;
if(
$square){
$dst_w = $maxd;
$dst_h = $maxd;
if(
$src_width>$src_height){
$src_x = ceil(($src_width-$src_height)/2);
$src_w=$src_height;
$src_h=$src_height;
}else{
$src_y = ceil(($src_height-$src_width)/2);
$src_w=$src_width;
$src_h=$src_width;
}
}else{
if(
$src_width>$src_height){
$dst_w=$maxd;
$dst_h=floor($src_height*($dst_w/$src_width));
}else{
$dst_h=$maxd;
$dst_w=floor($src_width*($dst_h/$src_height));
}
}
$dst_im=@imagecreatetruecolor($dst_w,$dst_h);
@
imagecopyresampled($dst_im, $src_im, 0, 0, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
@
imagejpeg($dst_im,$dpath);
return
$dst_im;
}
?>
asgaroth dot belem at gmail dot com
15 年前
如果您在重新取樣的圖片中遇到雜訊問題(就像我一樣)。

那麼將 imagecopyresampled() 更改為 imagecopyresized() 就可以消除雜訊,在這裡找到的:http://bugs.php.net/bug.php?id=45030

別問我為什麼。但它確實有效。
asgaroth dot belem at gmail dot com
15 年前
關於調整 PNG 大小時保留透明度,這是唯一對我有效的方法

<?php imagealphablending($new_watermark, false);
$color = imagecolortransparent($new_watermark, imagecolorallocatealpha($new_watermark, 0, 0, 0, 127));
imagefill($new_watermark, 0, 0, $color);
imagesavealpha($new_watermark, true);
imagecopyresampled($new_watermark, $watermark, 0, 0, 0, 0, $new_watermark_width, $new_watermark_height, imagesx($watermark),imagesy($watermark));
?>

嘗試但沒有成功

<?php imagealphablending($new_watermark, false);
$color = imagecolortransparent($new_watermark, imagecolorallocate($new_watermark, 0, 0, 0));
imagefill($new_watermark, 0, 0, $color);
imagesavealpha($new_watermark, true);
imagecopyresampled($new_watermark, $watermark, 0, 0, 0, 0, $new_watermark_width, $new_watermark_height, imagesx($watermark),imagesy($watermark));
?>

希望對某些人有幫助。
swizec at swizec dot com
16 年前
寫了一個用於清理使用者上傳圖片的函式。它會將原始圖片儲存為大約 800x600 的大小,以便在開啟時仍能適合大多數螢幕,並製作所需大小的縮圖,並將所有圖片轉換為高品質的 jpeg 格式,以減少頻寬使用。

縮圖的製作方式與設計師在 Photoshop 中製作的方式類似,首先將最麻煩的尺寸調整為所需大小,然後裁剪其餘部分,使圖像保持比例,並且大部分最終出現在縮圖中。

<?php

// $image 是 $_FILES[ <圖片名稱> ]
// $imageId 是此圖片在資料庫或其他地方使用的 ID
// $thumbWidth 和 $thumbHeight 是縮圖所需的尺寸
function processImage( $image, $imageId, $thumbWidth, $thumbHeight )
{
$type = $image[ 'type' ];
$galleryPath = 'images/collection/';

if (
strpos( $type, 'image/' ) === FALSE )
{
// 不是圖片
return FALSE;
}
$type = str_replace( 'image/', '', $type );
$createFunc = 'imagecreatefrom' . $type;

$im = $createFunc( $image[ 'tmp_name' ] );

$size = getimagesize( $image[ 'tmp_name' ] );

$w = $size[ 0 ];
$h = $size[ 1 ];
if (
$w > 800 || $h > 600 )
{
// 確保圖片不會太大
if ( $w > 800 )
{
$nw = 800;
$nh = ceil( $nw*($h/$w) );
}elseif(
$h > 600 )
{
$nh = 600;
$nw = ceil( $nh*($w/$h) );
}

$im2 = imagecreatetruecolor( $nw, $nh );
imagecopyresampled( $im2, $im, 0, 0, 0, 0, $nw, $nh, $w, $h );
imagedestroy( $im );

$im = $im2;
$w = $nw;
$h = $nh;
}

// 建立縮圖
$tw = $thumbWidth;
$th = $thumbHeight;
$imT = imagecreatetruecolor( $tw, $th );

if (
$tw/$th > $th/$tw )
{
// 較寬
$tmph = $h*($tw/$w);
$temp = imagecreatetruecolor( $tw, $tmph );
imagecopyresampled( $temp, $im, 0, 0, 0, 0, $tw, $tmph, $w, $h ); // 調整寬度大小
imagecopyresampled( $imT, $temp, 0, 0, 0, $tmph/2-$th/2, $tw, $th, $tw, $th ); // 裁切
imagedestroy( $temp );
}else
{
// 較高
$tmpw = $w*($th/$h );
$imT = imagecreatetruecolor( $tmpw, $th );
imagecopyresampled( $imT, $im, 0, 0, 0, 0, $tmpw, $h, $w, $h ); // 調整高度大小
imagecopyresampled( $imT, $temp, 0, 0, $tmpw/2-$tw/2, 0, $tw, $th, $tw, $th ); // 裁切
imagedestroy( $temp );
}

// 儲存圖片
imagejpeg( $im, $galleryPath . $imgid . '.jpg', 100 );
imagejpeg( $imT, $galleryPath . $imgid . '_thumb.jpg', 100 );
}

?>
arnar at netvistun dot is
16 年前
一個小型的縮圖腳本。可以讓你指定最大高度和寬度。縮圖將始終是矩形的,而圖片本身會保留其比例。非常乾淨。

<?php
// 檔案
$filename = 'a.jpg';

// 設定最大高度和寬度
$width = 80;
$height = 80;

$thumbsize = 80;

// 內容類型
header('Content-type: image/jpeg');

// 取得新的尺寸
list($width_orig, $height_orig) = getimagesize($filename);

$ratio_orig = $width_orig/$height_orig;

if (
$width/$height > $ratio_orig) {
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}

// 重新取樣
$image_p = imagecreatetruecolor($thumbsize, $thumbsize);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, -($width/2) + ($thumbsize/2), -($height/2) + ($thumbsize/2), 0, 0, $width, $height, $width_orig, $height_orig);

// 輸出
imagejpeg($image_p, null, 100);
?>
MBorgPL at gmail dot com
15 年前
zorroswordsman at gmail dot com 的調整大小類別的另一個補充。

該函式將 $_FILES['sent_image'] 作為第一個參數。第二個參數是完整的目的地路徑。

它只移動圖片。

如果成功,它會回傳目的地路徑,如果發生任何錯誤則回傳 false。

<?php
public function move_image($tmp_img, $dest_img)
{
//驗證上傳的檔案是否為圖片
if (strpos($tmp_img['type'], 'image') !== false)
{
//將上傳的檔案移動到目標位置
if (move_uploaded_file($tmp_img['tmp_name'], $dest_img)) {
return
$dest_img;
}
}
return
false;
}
?>
MBorg_PL
15 年前
對 zorroswordsman 在 gmail dot com 的調整大小類別以及 matt 在 rees-jenkins dot co dot uk 的補充進行了另一個小修改。此類別可以調整為不同的寬度和高度,而不僅僅是相同的大小。

<?php
// 設定最大圖片尺寸 (像素)
public function set_size($max_x = 100,$max_y = 100)
{

// 調整大小
if($this->x_input > $max_x || $this->y_input > $max_y)
{

$a= $max_x / $max_y;
$b= $this->x_input / $this->y_input;

if (
$a<$b)
{

$this->x_output = $max_x;
$this->y_output = ($max_x / $this->x_input) * $this->y_input;

}
else
{

$this->y_output = $max_y;
$this->x_output = ($max_y / $this->y_input) * $this->x_input;

}
// 完成

$this->resize = TRUE;

}

// 不調整大小
else { $this->resize = FALSE; }

}
?>

現在此類別的用法如下

<?php

##### 示範 #####

// 圖片
$src = "myimage.jpg";

// 開始
$img = new imaging;
$img->set_img($src);
$img->set_quality(80);

// 小型縮圖
$img->set_size(250,150);
$img->save_img("small_250x150_" . $src);

// 迷你縮圖
$img->set_size(50,250);
$img->save_img("baby_50x250_" . $src);

// 完成
$img->clear_cache();

?>
matt at rees-jenkins dot co dot uk
16 年前
對 zorroswordsman 在 gmail dot com 的調整大小類別進行了小修改。它僅在寬度和高度都大於所需尺寸時才調整大小。這應該可以修正此問題

<?php
// 設定最大圖片尺寸 (像素)
function set_size($size = 100)
{
// 調整大小
if($this->x_input > $size || $this->y_input > $size)
{
// 寬
if($this->x_input >= $this->y_input)
{
$this->x_output = $size;
$this->y_output = ($this->x_output / $this->x_input) * $this->y_input;
}
// 高
else
{
$this->y_output = $size;
$this->x_output = ($this->y_output / $this->y_input) * $this->x_input;
}
// 完成
$this->resize = TRUE;
}
// 不調整大小
else { $this->resize = FALSE; }
}
?>
eblejr AT phrebh DOT com
17 年前
Tim 的程式碼速度很快,但是如果您嘗試將重新取樣的圖片放置在左上角以外的任何位置,則該程式碼將無法運作。
crash
16 年前
將 GIF 轉換為 PNG 以保留透明度的建議很有用。但是,用於維持透明度的步驟也適用於 GIF,因此無需轉換步驟。只需執行相同的操作,並以 GIF 格式儲存即可。即:

<?php
$g_iw 是
圖片寬度
$g_ih 是
圖片高度

$img_src
=imagecreatefromgif($g_srcfile);
$img_dst=imagecreatetruecolor($g_iw,$g_ih);

//保留 alpha 透明度
imagecolortransparent($img_dst, imagecolorallocate($img_dst, 0, 0, 0));
imagealphablending($img_dst, false);
imagesavealpha($img_dst, true);
imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $g_iw, $g_ih, $g_is[0], $g_is[1]);

imagegif($img_dst, $g_dstfile);
imagedestroy($img_dst);
?>
rich at corephp dot co dot uk
17 年前
當調整圖片大小使其比原始圖片*更大*時,請注意此函式,因為記憶體消耗率很高。例如,一個 200KB 的 JPEG 檔案 (1024x768) 在載入時會佔用 4MB 的記憶體,但當重新取樣為兩倍大小時,記憶體使用量會躍升至 20.1MB。imagecopyresized 也是如此。處理真彩色圖片時,請允許每個*像素*大約 5 個位元組的記憶體。
rayg at daylongraphics dot com
16 年前
這裡有一個簡單的函式,可以將一個 JPEG 圖像檔案重新取樣到另一個檔案,同時保持來源圖像在目標尺寸內的長寬比。如果你產生太多周圍有細長空白區域的縮圖,你也可以調整允許的失真程度。放大圖像時也應該能正常運作。如果函式成功執行,則傳回 true,否則傳回 false。

function resample_picfile($src, $dst, $w, $h)
{
// 如果失真拉伸在以下範圍內,
// 則允許圖像失真。
$lowend = 0.8;
$highend = 1.25;

$src_img = imagecreatefromjpeg($src);
if($src_img)
{
$dst_img = ImageCreateTrueColor($w, $h);
/* 如果你不希望保留長寬比的圖像
有黑色背景,請在這裡使用你選擇的顏色填充 $dst_img。
*/

if($dst_img)
{
$src_w = imageSX($src_img);
$src_h = imageSY($src_img);

$scaleX = (float)$w / $src_w;
$scaleY = (float)$h / $src_h;
$scale = min($scaleX, $scaleY);

$dstW = $w;
$dstH = $h;
$dstX = $dstY = 0;

$scaleR = $scaleX / $scaleY;
if($scaleR < $lowend || $scaleR > $highend)
{
$dstW = (int)($scale * $src_w + 0.5);
$dstH = (int)($scale * $src_h + 0.5);

// 將圖片保持在框架的中心。
$dstX = (int)(0.5 * ($w - $dstW));
$dstY = (int)(0.5 * ($h - $dstH));
}

imagecopyresampled(
$dst_img, $src_img, $dstX, $dstY, 0, 0,
$dstW, $dstH, $src_w, $src_h);
imagejpeg($dst_img, $dst);
imagedestroy($dst_img);
}
imagedestroy($src_img);
return file_exists($dst);
}
return false;
}
matt1walsh DESPAMMER gmail dot com
17 年前
我所見過的任何調整透明 GIF 大小的東西都不能始終如一地產生好的圖像。我想到的一個技巧很笨拙,但效果還不錯 —— 將 GIF 轉換為 PNG。這個方法對我有效。

$g_iw 是新的圖像寬度
$g_ih 是新的圖像高度

$img_src=imagecreatefromgif($g_srcfile);
$img_dst=imagecreatetruecolor($g_iw,$g_ih);

//保留 alpha 透明度
imagecolortransparent($img_dst, imagecolorallocate($img_dst, 0, 0, 0));
imagealphablending($img_dst, false);
imagesavealpha($img_dst, true);
imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $g_iw, $g_ih, $g_is[0], $g_is[1]);

imagepng($img_dst, $g_dstfile);
imagedestroy($img_dst);
michael at heymichael dot com
15 年前
imagecopyresampled() 的效果非常棒,但這裡有一些不應該嘗試的用法

我寫的調整大小常式會尋找像素寬度,並根據「如果寬度和高度太大,則它們的位元組大小也會很大」的概念來調整圖像大小。一開始效果很好。

但是,當我看到一些巨大的位元組大小的圖像溜過我 1000px 寬的基準時,我認為如果較小寬度的圖像的 filesize() 超過 100K,則應該對其進行調整大小。

我的想法是,我會「調整」它們的大小,保持它們原始的寬度和高度(即在下面的 (1) 中,$newW = $oldW, $newH = $oldH),並讓下面的 (2) 中的「75」來減少位元組大小。

請勿嘗試這樣做。 imagecopyresampled() 會鎖定伺服器,嘗試將一個 800px 寬的圖像調整為「新」寬度 800px。(我是在我的 Windows 伺服器上發現這個問題的,然後才把它放到目標 Linux 伺服器上,所以請謹慎看待。)

我透過將 $newW 設為 ($picW * 0.99) 等來解決這個問題。這樣你就可以在不鎖定的情況下獲得所需的位元組大小縮減。

(1) imagecopyresampled($image_p, $image, 0, 0, 0, 0, $newW, $newH, $picW, $picH);

(2) imagejpeg($image_p, $theFile, 75);
areddan at silverarm dot ie
18 年前
<?php
// 檔案
$filein = ''; // 輸入檔案
$fileout = 'ttt.gif'; // 輸出檔案 - 可選

$imagethumbsize_w = 100; // 縮圖寬度 (從圖片中間裁切的區域)
$imagethumbsize_h = 75; // 縮圖高度 (從圖片中間裁切的區域)
resize_then_crop( $filein,$fileout,$imagethumbsize_w,
$imagethumbsize_h,/*rgb*/"255","255","255");

//作者:Alan Reddan Silverarm Solutions
//日期:2005/01/27
//適用於圖片的函式。
//它會將圖片縮放到最佳尺寸。例如,如果您有一張 200 X 100 的圖片,而您想要一個 75 X 50 的縮圖,
//它會先將圖片縮放到 100 X 50,
//然後從輸入圖片的中心取出 75 X 50 的部分。
//這樣可以保留大量的圖片資訊。
//如果您的輸入圖片是 100 X 200,則會先將圖片縮放到 75 X 150,然後從中心取出
//75 X 75 的部分。
//此處的優點是函式會自行決定是依寬度還是高度調整大小。
//它也會決定在縮圖為矩形的情況下,要使用高度還是寬度作為基準起始點。

function resize_then_crop( $filein,$fileout,
$imagethumbsize_w,$imagethumbsize_h,$red,$green,$blue)
{

// 取得新的尺寸
list($width, $height) = getimagesize($filein);
$new_width = $width * $percent;
$new_height = $height * $percent;

if(
preg_match("/.jpg/i", "$filein"))
{
$format = 'image/jpeg';
}
if (
preg_match("/.gif/i", "$filein"))
{
$format = 'image/gif';
}
if(
preg_match("/.png/i", "$filein"))
{
$format = 'image/png';
}

switch(
$format)
{
case
'image/jpeg':
$image = imagecreatefromjpeg($filein);
break;
case
'image/gif';
$image = imagecreatefromgif($filein);
break;
case
'image/png':
$image = imagecreatefrompng($filein);
break;
}

$width = $imagethumbsize_w ;
$height = $imagethumbsize_h ;
list(
$width_orig, $height_orig) = getimagesize($filein);

if (
$width_orig < $height_orig) {
$height = ($imagethumbsize_w / $width_orig) * $height_orig;
} else {
$width = ($imagethumbsize_h / $height_orig) * $width_orig;
}

if (
$width < $imagethumbsize_w)
//如果寬度小於提供的縮圖大小
{
$width = $imagethumbsize_w;
$height = ($imagethumbsize_w/ $width_orig) * $height_orig;;
}

if (
$height < $imagethumbsize_h)
//如果高度小於提供的縮圖大小
{
$height = $imagethumbsize_h;
$width = ($imagethumbsize_h / $height_orig) * $width_orig;
}

$thumb = imagecreatetruecolor($width , $height);
$bgcolor = imagecolorallocate($thumb, $red, $green, $blue);
ImageFilledRectangle($thumb, 0, 0, $width, $height, $bgcolor);
imagealphablending($thumb, true);

imagecopyresampled($thumb, $image, 0, 0, 0, 0,
$width, $height, $width_orig, $height_orig);
$thumb2 = imagecreatetruecolor($imagethumbsize_w , $imagethumbsize_h);
// 真實色彩,以獲得最佳品質
$bgcolor = imagecolorallocate($thumb2, $red, $green, $blue);
ImageFilledRectangle($thumb2, 0, 0,
$imagethumbsize_w , $imagethumbsize_h , $white);
imagealphablending($thumb2, true);

$w1 =($width/2) - ($imagethumbsize_w/2);
$h1 = ($height/2) - ($imagethumbsize_h/2);

imagecopyresampled($thumb2, $thumb, 0,0, $w1, $h1,
$imagethumbsize_w , $imagethumbsize_h ,$imagethumbsize_w, $imagethumbsize_h);

// 輸出
//header('Content-type: image/gif');
//imagegif($thumb); //測試時先輸出到瀏覽器第一個圖片

if ($fileout !="")imagegif($thumb2, $fileout); //寫入檔案
header('Content-type: image/gif');
imagegif($thumb2); //輸出到瀏覽器
}
?>
hoangvu4000 at gmail dot com
11 年前
我用來調整圖片大小並帶有 exif 資料的完整函式

<?php
function CreateThumbnail($pic,$thumb,$thumbwidth, $quality = 100)
{

$im1=ImageCreateFromJPEG($pic);
if(
function_exists("exif_read_data")){
$exif = exif_read_data($pic);
if(!empty(
$exif['Orientation'])) {
switch(
$exif['Orientation']) {
case
8:
$im1 = imagerotate($im1,90,0);
break;
case
3:
$im1 = imagerotate($im1,180,0);
break;
case
6:
$im1 = imagerotate($im1,-90,0);
break;
}
}
}
$info = @getimagesize($pic);

$width = $info[0];

$w2=ImageSx($im1);
$h2=ImageSy($im1);
$w1 = ($thumbwidth <= $info[0]) ? $thumbwidth : $info[0] ;

$h1=floor($h2*($w1/$w2));
$im2=imagecreatetruecolor($w1,$h1);

imagecopyresampled ($im2,$im1,0,0,0,0,$w1,$h1,$w2,$h2);
$path=addslashes($thumb);
ImageJPEG($im2,$path,$quality);
ImageDestroy($im1);
ImageDestroy($im2);

}
?>
aykuty at gmail dot com
6 年前
依比例縮放圖片,然後置中填滿畫布大小

<?php

/*
根據給定的最大值調整圖片大小,並以白色置中於畫布上。我為 trendyol 整合而寫。

Aykut YILDIZGÖRÜR
aykuty add gmail dot com
*/

function set_image2canvas($file, $new_file, $canvas_width=1200, $canvas_height =1800, $quality=100) {

if (!
file_exists( $new_file )) {

list(
$width, $height, $type, $attr) = getimagesize( $file );

if(
$width> $height) {
$width_tt=$canvas_width;
$height_tt=round($height/$width*$canvas_width);
$off_y = ceil(( $canvas_height - $height_tt)/2);
$off_x=0;

} else {
$height_tt=$canvas_height;
$width_tt=round($width/$height*$canvas_height);
$off_x=ceil(($canvas_width - $width_tt)/2);
$off_y=0;
}

$thumb=imagecreatefromjpeg( $file );
$thumb_p = imagecreatetruecolor($canvas_width, $canvas_height);

$bg = imagecolorallocate ( $thumb_p, 255, 255, 255 );
imagefill ( $thumb_p, 0, 0, $bg );
imagecopyresampled($thumb_p, $thumb, $off_x, $off_y, 0, 0, $width_tt, $height_tt, $width, $height);

imagejpeg($thumb_p,$new_file,$quality);

}else{
//目標圖片已存在
return -1;
}
}
?>
Michael Shepanski
16 年前
這是一個我想分享的函式,它將重新取樣並複製具有圓角的圖片。

<?php
/** ------------------------------------------------------------
* 複製並重新取樣具有圓角的圖像。
* ----------------------------------------------------------- */
function imageRoundedCopyResampled(&$dstimg, &$srcimg, $dstx, $dsty, $srcx,
$srcy, $dstw, $dsth, $srcw, $srch, $radius) {
# 調整來源圖像大小
$srcResized = imagecreatetruecolor($dstw, $dsth);
imagecopyresampled($srcResized, $srcimg, 0, 0, $srcx, $srcy,
$dstw, $dsth, $srcw, $srch);
# 複製沒有角落的主體部分
imagecopy($dstimg, $srcResized, $dstx+$radius, $dsty,
$radius, 0, $dstw-($radius*2), $dsth);
imagecopy($dstimg, $srcResized, $dstx, $dsty+$radius,
0, $radius, $dstw, $dsth-($radius*2));
# 建立迭代列表;array(array(X1, X2, CenterX, CenterY), ...)
# 迭代順序為:左上、右上、左下、右下
$iterations = array(
array(
0, 0, $radius, $radius),
array(
$dstw-$radius, 0, $dstw-$radius, $radius),
array(
0, $dsth-$radius, $radius, $dsth-$radius),
array(
$dstw-$radius, $dsth-$radius, $dstw-$radius, $dsth-$radius)
);
# 循環遍歷每個角落的「迭代」
foreach($iterations as $iteration) {
list(
$x1,$y1,$cx,$cy) = $iteration;
for (
$y=$y1; $y<=$y1+$radius; $y++) {
for (
$x=$x1; $x<=$x1+$radius; $x++) {
# 如果 (X,Y)->(CX,CY) 的長度小於半徑,則繪製該點
$length = sqrt(pow(($cx - $x), 2) + pow(($cy - $y), 2));
if (
$length < $radius) {
imagecopy($dstimg, $srcResized, $x+$dstx, $y+$dsty,
$x, $y, 1, 1);
}
}
}
}
}
?>
To Top