从您的问题中看来,您似乎还不太了解GD库,我会分享一些我的经验,也许有点离题,但我认为对于像您这样的新手来说会很有帮助:
步骤1,验证文件。使用以下函数检查$_FILES['image']['tmp_name']
文件是否为有效文件:
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']);
第二步,获取文件格式使用finfo扩展库中的以下函数来检查文件(内容)的文件格式。你可能会问为什么不直接使用$_FILES["image"]["type"]
来检查文件格式?因为它仅检查文件扩展名而不是文件内容,如果有人将原本名为world.png的文件重命名为world.jpg,$_FILES["image"]["type"]
将返回jpeg而不是png,所以$_FILES["image"]["type"]
可能会返回错误的结果。
function getFormatFromContents($contents)
}
$format = getFormatFromContents($contents);
第三步,获取GD资源 从之前的内容中获取GD资源:
function getGDResourceFromContents($contents) {
$resource = @imagecreatefromstring($contents);
if ($resource == false) {
throw new \Exception('Cannot process image');
}
return $resource;
}
$resource = getGDResourceFromContents($contents);
第四步,获取图片尺寸现在你可以使用以下简单的代码来获取图片的尺寸:
$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');
第六步,调整图像大小 使用上述步骤中获取的$args
、$width
、$height
、$format
和$resource参数,将它们传入以下函数中,并获得调整大小后的新资源:
function runResize($width, $height, $format, $resource, $args) {
if ($args === false) {
return;
}
$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);
第七步,获取新内容,使用以下函数从新的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);
第九步:保存图像如果我们有一个名为Mike的用户,您可以执行以下操作,它将保存到与此php脚本相同的文件夹中:
$user_name = 'mike';
$filename = $user_name . '.' . $extension;
file_put_contents($filename, $newcontents);
步骤10 销毁资源 别忘了销毁GD资源!
imagedestroy($newresource);
你可以将所有的代码写入一个类中,并使用以下代码进行调用:
public function __destruct() {
@imagedestroy($this->resource);
}
提示
我建议不要转换用户上传的文件格式,否则您会遇到很多问题。