可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm using a neat little php script to resize my images to fit in a 300x300 pixel square, while keeping the aspect ratio. I got the script from here.
Here is the whole script:
<?php
/*
* File: SimpleImage.php
* Author: Simon Jarvis
* Copyright: 2006 Simon Jarvis
* Date: 08/11/06
* Link: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
* http://www.gnu.org/licenses/gpl.html
*
*/
class SimpleImage {
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
if( $this->image_type == IMAGETYPE_JPEG ) {
$this->image = imagecreatefromjpeg($filename);
} elseif( $this->image_type == IMAGETYPE_GIF ) {
$this->image = imagecreatefromgif($filename);
} elseif( $this->image_type == IMAGETYPE_PNG ) {
$this->image = imagecreatefrompng($filename);
}
}
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image,$filename,$compression);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image,$filename);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image,$filename);
}
if( $permissions != null) {
chmod($filename,$permissions);
}
}
function output($image_type=IMAGETYPE_JPEG) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image);
}
}
function getWidth() {
return imagesx($this->image);
}
function getHeight() {
return imagesy($this->image);
}
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$height);
}
function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
function scale($scale) {
$width = $this->getWidth() * $scale/100;
$height = $this->getheight() * $scale/100;
$this->resize($width,$height);
}
function resize($width,$height) {
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
}
}
?>
and here's how I'm using it:
$image = new SimpleImage();
$image->load($_FILES['uploaded_image']['tmp_name']);
$image->resizeToWidth(300);
$image->resizeToHeight(300);
$image->save('./images/photo'.$id.'.jpg');
header("Location: people.php");
exit;
And here's my problem:
It only resizes the height. So if I gave it a 1200x990 (width x height) image, it spits out a
400x300 (if that makes sense), which is does not fit within my 300x300 square.
I also tried:
$image = new SimpleImage();
$image2 = new SimpleImage();
$image->load($_FILES['uploaded_image']['tmp_name']);
$image->resizeToWidth(300);
$image->save('temp.jpg');
$image2->load('temp.jpg');
$image2->resizeToHeight(300);
$image2->save('./images/photo'.$id.'.jpg');
unlink('temp.jpg');
header("Location: people.php");
exit;
Sorry for the horrid mass of code, I thought I had better include the source just in case the place where I got it from moves or shuts down.
Any godly coders out there?
回答1:
It's working correctly - it's resizing to a height of 300 and keeping the aspect ratio (which, in this case, makes the width 400). You need to see which side is the biggest side (or, more accurately, the side furthest from the aspect ratio you require) first, and then only call one function (resizeToWidth() or resizeToHeight()).
If I had to use that class, I think this will work:
$image = new SimpleImage();
$size = getImageSize($_FILES['uploaded_image']['tmp_name']);
if ($size[0] > 300) {
$image->load($_FILES['uploaded_image']['tmp_name']);
$image->resizeToWidth(300);
$image->save('./images/photo'.$id.'.jpg');
} else {
move_uploaded_file($_FILES['uploaded_image']['tmp_name'], './images/photo'.$id.'.jpg');
}
$size = getImageSize('./images/photo'.$id.'.jpg');
if ($size[1] > 300) {
$image->load('./images/photo'.$id.'.jpg');
$image->resizeToHeight(300);
$image->save('./images/photo'.$id.'.jpg');
}
header("Location: people.php");
exit;
回答2:
You can make use of the imagescale()
available from PHP 5.5.0
to simplify your process of re-sizing/scaling images.
Such that...
$imgresource = imagecreatefromjpeg("pathtoyourimage.jpg");
imagescale($imgresource, 500, 900, IMG_BICUBIC);
回答3:
Add fitToSquare function to SimpleImage class, this functions calculate the x and y coordinates of the source image, then crop as square. I haven't test my function:) But it seems ok.
function fitToSquare($width) {
$new_image = imagecreatetruecolor($width, $height);
$sourceX = 0;
$sourceY = 0;
if($this->getWidth() > $this->getHeight())
{
$sourceX = ($this->getWidth() - $this->getHeight()) / 2;
}
else
{
$sourceY = ($this->getHeight() - $this->getWidth()) / 2;
}
imagecopyresampled($new_image, $this->image, 0, 0, $sourceX, $sourceY, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
}
回答4:
function imageResize($filename, $dest, $ndest,$filetempname,$filename) {
$userfile_name = (isset($filename) ? $filename : "");
$mb_byte_2 = (1024 * 2 * 1000);
$ftmp = $filetempname;
$oname = $filename;
$fname = $dest;
$sizes = getimagesize($ftmp);
$width = $sizes[0];
$height = $sizes[1];
$extenssion = strstr($oname, ".");
$prod_img = $fname;
$prod_img_thumb =$ndest;
move_uploaded_file($ftmp, $prod_img);
$original_filesize = (filesize($prod_img) / 1024);
$sizes = getimagesize($prod_img);
$expected_max_width = 125;
$expected_max_height = 100;
$originalw = $sizes[0];
$originalh = $sizes[1];
if ($originalh < $expected_max_height) {
if ($originalw < $expected_max_width) {
$imgwidth = $originalw;
$imgheight = $originalh;
} else {
$imgheight = ($expected_max_width * $originalh) / $originalw;
$imgwidth = $expected_max_width;
}
} else {
$new_height = $expected_max_height;
$new_width = ($expected_max_height * $originalw) / $originalh;
if ($new_width > $expected_max_width) {
$new_height = ($expected_max_width * $expected_max_height) / $new_width;
$new_width = $expected_max_width;
}
$imgwidth = $new_width;
$imgheight = $new_height;
}
$new_h = $imgheight;
$new_w = $imgwidth;
$new_w_im = '125';
$new_h_im = '100';
$offsetwidth = $new_w_im - $new_w;
$offsetw = $offsetwidth / 2;
$offsetheight = $new_h_im - $new_h;
$offseth = $offsetheight / 2;
// echo $extenssion;
$dest = imagecreatetruecolor($new_w_im, $new_h_im);
$bg = imagecolorallocate($dest, 255, 255, 255);
imagefill($dest, 0, 0, $bg);
if ($extenssion == '.jpg') {
$src = imagecreatefromjpeg($prod_img)
or die('Problem In opening Source JPG Image');
} elseif ($extenssion == '.jpeg') {
$src = imagecreatefromjpeg($prod_img)
or die('Problem In opening Source JPEG Image');
} elseif ($extenssion == '.gif') {
$src = imagecreatefromgif($prod_img)
or die('Problem In opening Source GIF Image');
} elseif ($extenssion == '.png') {
$src = imagecreatefrompng($prod_img)
or die('Problem In opening Source PNG Image');
} elseif ($extenssion == '.bmp') {
//print_r($prod_img);
// $src = imagecreatefrombmp($prod_img)
// or die('Problem In opening Source BMP Image');
}
if (function_exists('imagecopyresampled')) {
imagecopyresampled($dest, $src, $offsetw, $offseth, 0, 0,
$new_w, $new_h, imagesx($src), imagesy($src))
or die('Problem In resizing');
} else {
Imagecopyresized($dest, $src, $offsetw, $offseth, 0, 0,
$new_w, $new_h, imagesx($src), imagesy($src))
or die('Problem In resizing');
}
imagejpeg($dest, $prod_img_thumb, 72)
or die('Problem In saving');
imagedestroy($dest);
@ob_flush();
$new_filesize = (filesize($prod_img) / 1024);
}
回答5:
If it's giving you problems, you can back door it. Instead of letting the class calculate the ratios, go straight to the resize function.
$image = new SimpleImage();
$image->load($_FILES['uploaded_image']['tmp_name']);
$image->resize(300, 300);
$image->save('./images/photo'.$id.'.jpg');
header("Location: people.php");
exit;
回答6:
you cannot do resizetowidth and then resizetoheight.
this will in fact resize it to 363x300.
create a new function which preserves the aspect ratio:
function scale_kar($maxwidth,$maxheight) {
$width = $this->getWidth();
$height = $this->getheight();
if($width > $height) {
$ratio = $maxwidth / $width;
$height = $height * $ratio;
$this->resize($maxwidth,$height);
}
if($width < $height) {
$ratio = $maxheight / $height;
$width = $width * $ratio;
$this->resize($width,$maxheight);
}
}
then call it with:
$image->scale_kar(300,300);
回答7:
I fixed the function posted by @adenizc and created a pull-request to the SimpleImage library. Here is the function:
/**
* Square crop
*
* This function crops the image to fit the given size which is both the width and the height
*
* @param int $size
*
* @return SimpleImage
*/
function square($size) {
$new = imagecreatetruecolor($size, $size);
$sourceX = 0;
$sourceY = 0;
if($this->width > $this->height) {
$this->fit_to_height($size);
$sourceX = ($this->width - $size) / 2;
}
else {
$this->fit_to_width($size);
$sourceY = ($this->height - $size) / 2;
}
imagealphablending($new, false);
imagesavealpha($new, true);
imagecopy($new, $this->image, 0, 0, $sourceX, $sourceY, $size, $size);
$this->image = $new;
return $this;
}