【发布时间】:2011-10-21 04:40:17
【问题描述】:
如何通过上传过程自动裁剪图像?有没有 php 函数可以做到这一点?
我希望我的网页通过裁剪从原始图像的各个维度显示具有相同维度的图像。
或者有什么想法?
【问题讨论】:
标签: php javascript jquery
如何通过上传过程自动裁剪图像?有没有 php 函数可以做到这一点?
我希望我的网页通过裁剪从原始图像的各个维度显示具有相同维度的图像。
或者有什么想法?
【问题讨论】:
标签: php javascript jquery
如果不知道主题在哪里,自动裁剪会很困难。也许您可以尝试获得一个内部居中的矩形,如图所示:
首先要做的是找到原始图像尺寸和文件类型。您不应该信任图像扩展名,而应使用 getimagesize 。尽管名称 getimagesize 不仅返回大小,还返回文件类型。
//width is at index 0, height at index 1, mime type at ['mime'] key
$original = getimagesize($filename);
然后你应该构建一个内部 PHP 数据结构来将源图像保存在内存中,这样你就可以使用 imagecreatefromjpeg 或 imagecreatefrompng 或 imagecreatefromgif 来操作它,具体取决于图像类型。例如:
$srcImage = imagecreatefromjpeg($filename);
接下来,您应该分配另一个数据结构来保存目标图像。在这种情况下,我们没有图像开始,所以我分配了一个空图像。
$dstImage = imagecreatetruecolor($newWidth, $newHeight);
接下来,您应该将原始图像的一部分复制到目标图像。如果不想调整大小,请使用imagecopy,否则如果要裁剪和调整大小,可以考虑imagecopyresampled。
imagecopy(dstImage, $srcImage, 0, 0, $srcX, $srcY, $srcW, $srcH);
其中 $srcX 是源图像中的起始 X 点,$srcY 是起始 Y 点,$srcW 是从起始 X 点开始复制的宽度,$srcH 是要复制的区域的高度。
最后,您可以通过以下方式保存您的图片:
imagejpeg($this->dstImage, $filename, 90);
或者您可以将其输出到浏览器:
imagejpeg($this->dstImage);
如果您保存图像,您必须考虑将其保存在哪个目录中,如果您有很多图像(数千张或更多),请考虑将它们拆分为多个子目录的方法。
如果您保存原始图像,切勿保存扩展名不在您允许的扩展名列表中的图像,否则这将是一个巨大的安全漏洞,攻击者可以在其中向您发送和执行任何 PHP 代码网站。
基于所描述的概念,我编写了一个小类:
class ImageCrop {
//Image resources
private $srcImage, $dstImage;
//original width and height
private $width, $height;
/**
* Read an image from disk.
* @return true in case of success, false otherwise.
*/
public function openImage($filename) {
if (!file_exists($filename)) {
return false;
}
$original = getimagesize($filename);
switch ($original['mime']) {
case 'image/jpeg':
$this->srcImage = imagecreatefromjpeg($filename);
break;
case 'image/png':
$this->srcImage = imagecreatefrompng($filename);
break;
case 'image/gif':
$this->srcImage = imagecreatefromgif($filename);
break;
default:
return false;
}
$this->width = $original[0];
$this->height = $original[1];
return true;
}
/**
* Crop an image to the new specified dimension trying to get an
* internal rectangle of the original image. No crop is done if the
* original dimension is already smaller than $newWidth or $newHeight.
*/
public function crop($newWidth, $newHeight) {
$this->dstImage = imagecreatetruecolor($newWidth, $newHeight);
$srcX = $srcY;
$srcW = $this->width;
$srcH = $this->height;
$extraWidth = $this->width - $newWidth;
if ($extraWidth > 0) {
$srcX = $extraWidth / 2;
}
$extraHeight = $this->height - $newHeight;
if ($extraHeight > 0) {
$srcY = $extraHeight / 2;
}
imagecopy($this->dstImage, $this->srcImage, 0, 0,
$srcX, $srcY, $srcW, $srcH);
}
/**
* Save the destination image, the crop function should have been
* called already.
*/
public function save($filename) {
imagejpeg($this->dstImage, $filename, 90);
}
/**
* Output the destination image to the browser.
*/
public function output() {
imagejpeg($this->dstImage);
}
}
将类保存在ImageCrop.php中,示例用法:
require_once 'ImageCrop.php';
$imageCrop = new ImageCrop();
if ($imageCrop->openImage('big.jpg')) {
$imageCrop->crop(200, 300); //newWidth, newHeight
$imageCrop->save('small.jpg');
}
或者,要将输出直接发送到浏览器,请使用$imageCrop->output();。
【讨论】:
请以max_size.php 表示此人
<?php header('Content-type: image/jpeg');
function resampleimage($maxsize, $sourcefile, $imgcomp=0){
$g_imgcomp=100-$imgcomp;
if(file_exists($sourcefile)){
$g_is=getimagesize($sourcefile);
if($g_is[0] <= $maxsize && $g_is[1] <= $maxsize){
$new_width=$g_is[0];
$new_height=$g_is[1];
} else {
$w_adjust = ($maxsize / $g_is[0]);
$h_adjust = ($maxsize / $g_is[1]);
if($w_adjust <= $h_adjust){
$new_width=($g_is[0]*$w_adjust);
$new_height=($g_is[1]*$w_adjust);
} else {
$new_width=($g_is[0]*$h_adjust);
$new_height=($g_is[1]*$h_adjust);
}
}
$image_type = strtolower(strrchr($sourcefile, "."));
switch($image_type) {
case '.jpg':
$img_src = imagecreatefromjpeg($sourcefile);
break;
case '.jpeg':
$img_src = imagecreatefromjpeg($sourcefile);
break;
case '.png':
$img_src = imagecreatefrompng($sourcefile);
break;
case '.gif':
$img_src = imagecreatefromgif($sourcefile);
break;
default:
echo("Error Invalid Image Type");
die;
break;
}
$img_dst=imagecreatetruecolor($new_width,$new_height);
imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $new_width, $new_height, $g_is[0], $g_is[1]);
imagejpeg($img_dst);
imagedestroy($img_dst);
return true;
} else {
return false;
}
}
resampleimage($_GET['maxsize'], $_GET['source']);
?>
在你有图片的页面中
<img id="img" src="max_size.php?maxsize=152&source=[some image path]" />
【讨论】: