PHP: Resize/making thumbnails? - php

Helo i now have finish making my upload profilephoto system. Now i want include creating thumbnails of the uploaded image in different sizes eg 48x48 and 148x50, how can i do this?
Example / good tutorials for this?

You will need to use PHP's GD library or ImageMagick library.
First find out which, if any, you have installed on your development and production environments.
Then start looking for tutorials depending on which one you want to use. There are many out there.
GD usually comes pre-packed with PHP5.

Back then I used imagemagick.
$ convert -resize 48x48 xyz.jpg xyz_48x48.jpg
It is also available as a php module: http://php.net/manual/en/book.imagick.php
But I haven't used that one, but I suppose it knows exactly the same as the command line variant.

Tutorial with imagecreatefrom()... , imagecopyresized(), imagejpeg()

Here my class for resizing. Replace the 150 occurences with a variable.
<?php
/**
* Takes an image and creates a thumbnail of it.
*/
class ImageThumbnail
{
private $thumbnail;
/**
* Create a new object
*
* #param string $source Location of the original image (can be null if set using create())
* #param string $extension File extension, if it has been obfuscated (e.g. moved to PHP's tmp dir)
*/
public function __construct($source, $extension)
{
if ($source)
{
$this->create($source, $extension);
}
}
public function create($source, $extension = null)
{
if (!$extension)
{
$parts = explode('.', $source); // get the file extension
$extension = array_pop($parts);
}
else
{
$extension = ltrim($extension, '.'); // get rid of any prefixing dots
}
// Get the images size
$size = getImageSize($source);
// Width > height
if ($size[0] > $size[1])
{
$width = 150;
$height = (int) (150 * $size[1] / $size[0]);
}
// Height > width
else
{
$width = (int) (150 * $size[0] / $size[1]);
$height = 150;
}
$readFunc = 'imageCreateFrom'.filenameToImageMime($source);
if (!$source = $readFunc($source))
{
throw new Exception('The source image is unreadable');
}
// Create an blank image for the thumbnail
$thumbnail = imageCreateTrueColor($width, $height);
// Copy source image onto new image
imageCopyResized($thumbnail, $source, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
$this->thumbnail = $thumbnail;
}
public function getThumbnail()
{
return $this->thumbnail;
}
public function move($target)
{
$func = 'image'.filenameToImageMime($target);
$func($this->thumbnail, $target);
imageDestroy($this->thumbnail);
}
}

function makenicepic($srcfile,$tofile,$maxwidth,$maxheight) {
//global $_SGLOBAL;
// check file exist
if (!file_exists($srcfile)) {
return '';
}
$dstfile = $tofile;
include_once(S_ROOT.'./data/data_setting.php');
// //size
$tow = $maxwidth;
$toh =$maxheight;
$make_max = 0;
$maxtow = 950;
$maxtoh = 700;
$make_max = 1;
$im = '';
if($data = getimagesize($srcfile)) {
if($data[2] == 1) {
$make_max = 0;//gif skip
if(function_exists("imagecreatefromgif")) {
$im = imagecreatefromgif($srcfile);
}
} elseif($data[2] == 2) {
if(function_exists("imagecreatefromjpeg")) {
$im = imagecreatefromjpeg($srcfile);
}
} elseif($data[2] == 3) {
if(function_exists("imagecreatefrompng")) {
$im = imagecreatefrompng($srcfile);
}
}
}
if(!$im) return '';
$srcw = imagesx($im);
$srch = imagesy($im);
$towh = $tow/$toh;
$srcwh = $srcw/$srch;
if($towh <= $srcwh){
$ftow = $tow;
$ftoh = $ftow*($srch/$srcw);
$fmaxtow = $maxtow;
$fmaxtoh = $fmaxtow*($srch/$srcw);
} else {
$ftoh = $toh;
$ftow = $ftoh*($srcw/$srch);
$fmaxtoh = $maxtoh;
$fmaxtow = $fmaxtoh*($srcw/$srch);
}
if($srcw <= $maxtow && $srch <= $maxtoh) {
$make_max = 0;
}
if($srcw > $tow || $srch > $toh) {
if(function_exists("imagecreatetruecolor") && function_exists("imagecopyresampled") && #$ni = imagecreatetruecolor($ftow, $ftoh)) {
imagecopyresampled($ni, $im, 0, 0, 0, 0, $ftow, $ftoh, $srcw, $srch);
if($make_max && #$maxni = imagecreatetruecolor($fmaxtow, $fmaxtoh)) {
imagecopyresampled($maxni, $im, 0, 0, 0, 0, $fmaxtow, $fmaxtoh, $srcw, $srch);
}
} elseif(function_exists("imagecreate") && function_exists("imagecopyresized") && #$ni = imagecreate($ftow, $ftoh)) {
imagecopyresized($ni, $im, 0, 0, 0, 0, $ftow, $ftoh, $srcw, $srch);
if($make_max && #$maxni = imagecreate($fmaxtow, $fmaxtoh)) {
imagecopyresized($maxni, $im, 0, 0, 0, 0, $fmaxtow, $fmaxtoh, $srcw, $srch);
}
} else {
return '';
}
if(function_exists('imagejpeg')) {
imagejpeg($ni, $dstfile);
//big pic
if($make_max) {
imagejpeg($maxni, $srcfile);
}
} elseif(function_exists('imagepng')) {
imagepng($ni, $dstfile);
if($make_max) {
imagepng($maxni, $srcfile);
}
}
imagedestroy($ni);
if($make_max) {
imagedestroy($maxni);
}
}
imagedestroy($im);
if(!file_exists($dstfile)) {
return '';
} else {
return $dstfile;
}
}

Related

Cropping an image using php

I'm trying to crop an image when it has been uploaded. So far I've only managed to resize it but if an image is a rectangular shape then the image is squashed which doesn't look nice. I'm trying to get coding that I can use with the function that I currently have to resize. The ones that I'm seeing I have to change my function and I'm hoping not to do that.
Here is my function
function createThumbnail($filename) {
global $_SITE_FOLDER;
//require 'config.php';
$final_width_of_image = 82;
$height = 85;
$path_to_image_directory = $_SITE_FOLDER.'portfolio_images/';
$path_to_thumbs_directory = $_SITE_FOLDER.'portfolio_images/thumbs/';
if(preg_match('/[.](jpg)$/', $filename)) {
$im = imagecreatefromjpeg($path_to_image_directory . $filename);
} else if (preg_match('/[.](gif)$/', $filename)) {
$im = imagecreatefromgif($path_to_image_directory . $filename);
} else if (preg_match('/[.](png)$/', $filename)) {
$im = imagecreatefrompng($path_to_image_directory . $filename);
}
$ox = imagesx($im);
$oy = imagesy($im);
$nx = $final_width_of_image;
$ny = floor($oy * ($final_width_of_image / $ox));
//$ny = $height;
$nm = imagecreatetruecolor($nx, $ny);
imagecopyresized($nm, $im, 0,0,0,0,$nx,$ny,$ox,$oy);
if(!file_exists($path_to_thumbs_directory)) {
if(!mkdir($path_to_thumbs_directory)) {
die("There was a problem. Please try again!");
}
}
imagejpeg($nm, $path_to_thumbs_directory . $filename);
$tn = '<img src="' . $path_to_thumbs_directory . $filename . '" alt="image" />';
$tn .= '<br />Congratulations. Your file has been successfully uploaded, and a thumbnail has been created.';
echo $tn;
}
Here is my function.
<?php
function crop($file_input, $file_output, $crop = 'square',$percent = false) {
list($w_i, $h_i, $type) = getimagesize($file_input);
if (!$w_i || !$h_i) {
echo 'Unable to get the length and width of the image';
return;
}
$types = array('','gif','jpeg','png');
$ext = $types[$type];
if ($ext) {
$func = 'imagecreatefrom'.$ext;
$img = $func($file_input);
} else {
echo 'Incorrect file format';
return;
}
if ($crop == 'square') {
$min = $w_i;
if ($w_i > $h_i) $min = $h_i;
$w_o = $h_o = $min;
} else {
list($x_o, $y_o, $w_o, $h_o) = $crop;
if ($percent) {
$w_o *= $w_i / 100;
$h_o *= $h_i / 100;
$x_o *= $w_i / 100;
$y_o *= $h_i / 100;
}
if ($w_o < 0) $w_o += $w_i;
$w_o -= $x_o;
if ($h_o < 0) $h_o += $h_i;
$h_o -= $y_o;
}
$img_o = imagecreatetruecolor($w_o, $h_o);
imagecopy($img_o, $img, 0, 0, $x_o, $y_o, $w_o, $h_o);
if ($type == 2) {
return imagejpeg($img_o,$file_output,100);
} else {
$func = 'image'.$ext;
return $func($img_o,$file_output);
}
}
?>
And you can call like this
crop($file_input, $file_output, $crop = 'square',$percent = false);
And also resize function if you need.
<?php
function resize($file_input, $file_output, $w_o, $h_o, $percent = false) {
list($w_i, $h_i, $type) = getimagesize($file_input);
if (!$w_i || !$h_i) {
return;
}
$types = array('','gif','jpeg','png');
$ext = $types[$type];
if ($ext) {
$func = 'imagecreatefrom'.$ext;
$img = $func($file_input);
} else {
return;
}
if ($percent) {
$w_o *= $w_i / 100;
$h_o *= $h_i / 100;
}
if (!$h_o) $h_o = $w_o/($w_i/$h_i);
if (!$w_o) $w_o = $h_o/($h_i/$w_i);
$img_o = imagecreatetruecolor($w_o, $h_o);
imagecopyresampled($img_o, $img, 0, 0, 0, 0, $w_o, $h_o, $w_i, $h_i);
if ($type == 2) {
return imagejpeg($img_o,$file_output,100);
} else {
$func = 'image'.$ext;
return $func($img_o,$file_output);
}
}
?>
resize($file_input, $file_output, $w_o, $h_o, $percent = false);
You can use SimpleImage class found here SimpleImage
[edit] Updated version with many more features here SimleImage Updated
I use this when resizing various images to a smaller thumbnail size while maintaining aspect ratio and exact image size output. I fill the blank area with a colour that suits the background for where the image will be placed, this class supports cropping. Explore the methods cutFromCenter and maxareafill.
For example in your code you would not need to imagecreatefromjpeg() you would simply;
Include the class include('SimpleImage.php');
then;
$im = new SimpleImage();
$im->load($path_to_image_directory . $filename);
$im->maxareafill($output_width,$output_height, 0,0,0); // rgb
$im->save($path_to_image_directory . $filename);
I use this class daily and find it very versatile.

Magento + Imagemagick Proportional Images

Implemented Imagemagick instead of GD2 in Magento 1.7.0.2 as suggested here:
http://www.magentocommerce.com/boards/v/viewthread/6158/P135/#t328638
However the new images are not proportional, causing stretching. They were perfect with GD2
Instructions:
In the Gd2.php file, in the save() function comment out
call_user_func_array($this->_getCallback('output'), $functionParameters);
This is the where Magento calls the imagejpeg() function. Yuck.
Now add the following code just below the commented out line.
$source_file = $this->_fileSrcPath.'/'.$this->_fileSrcName;
$image_info = getimagesize($source_file);
$im = new Imagick();
$im->readImage($source_file);
//check to see if image needs to be resized (eg. thumbnails)
if ($image_info[0] != $this->_imageSrcWidth) {
$im->thumbnailImage($this->_imageSrcWidth, $this->_imageSrcHeight);
}
$im->writeImage($fileName);
Here is the implemented code
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license#magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* #category Varien
* #package Varien_Image
* #copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
* #license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
class Varien_Image_Adapter_Gd2 extends Varien_Image_Adapter_Abstract
{
protected $_requiredExtensions = Array("gd");
private static $_callbacks = array(
IMAGETYPE_GIF => array('output' => 'imagegif', 'create' => 'imagecreatefromgif'),
IMAGETYPE_JPEG => array('output' => 'imagejpeg', 'create' => 'imagecreatefromjpeg'),
IMAGETYPE_PNG => array('output' => 'imagepng', 'create' => 'imagecreatefrompng'),
IMAGETYPE_XBM => array('output' => 'imagexbm', 'create' => 'imagecreatefromxbm'),
IMAGETYPE_WBMP => array('output' => 'imagewbmp', 'create' => 'imagecreatefromxbm'),
);
/**
* Whether image was resized or not
*
* #var bool
*/
protected $_resized = false;
public function open($filename)
{
$this->_fileName = $filename;
$this->getMimeType();
$this->_getFileAttributes();
$this->_imageHandler = call_user_func($this->_getCallback('create'), $this->_fileName);
}
public function save($destination=null, $newName=null)
{
$fileName = ( !isset($destination) ) ? $this->_fileName : $destination;
if( isset($destination) && isset($newName) ) {
$fileName = $destination . "/" . $newName;
} elseif( isset($destination) && !isset($newName) ) {
$info = pathinfo($destination);
$fileName = $destination;
$destination = $info['dirname'];
} elseif( !isset($destination) && isset($newName) ) {
$fileName = $this->_fileSrcPath . "/" . $newName;
} else {
$fileName = $this->_fileSrcPath . $this->_fileSrcName;
}
$destinationDir = ( isset($destination) ) ? $destination : $this->_fileSrcPath;
if( !is_writable($destinationDir) ) {
try {
$io = new Varien_Io_File();
$io->mkdir($destination);
} catch (Exception $e) {
throw new Exception("Unable to write file into directory '{$destinationDir}'. Access forbidden.");
}
}
if (!$this->_resized) {
// keep alpha transparency
$isAlpha = false;
$isTrueColor = false;
$this->_getTransparency($this->_imageHandler, $this->_fileType, $isAlpha, $isTrueColor);
if ($isAlpha) {
if ($isTrueColor) {
$newImage = imagecreatetruecolor($this->_imageSrcWidth, $this->_imageSrcHeight);
} else {
$newImage = imagecreate($this->_imageSrcWidth, $this->_imageSrcHeight);
}
$this->_fillBackgroundColor($newImage);
imagecopy(
$newImage,
$this->_imageHandler,
0, 0,
0, 0,
$this->_imageSrcWidth, $this->_imageSrcHeight
);
$this->_imageHandler = $newImage;
}
}
$functionParameters = array();
$functionParameters[] = $this->_imageHandler;
$functionParameters[] = $fileName;
// set quality param for JPG file type
if (!is_null($this->quality()) && $this->_fileType == IMAGETYPE_JPEG)
{
$functionParameters[] = $this->quality();
}
// set quality param for PNG file type
if (!is_null($this->quality()) && $this->_fileType == IMAGETYPE_PNG)
{
$quality = round(($this->quality() / 100) * 10);
if ($quality < 1) {
$quality = 1;
} elseif ($quality > 10) {
$quality = 10;
}
$quality = 10 - $quality;
$functionParameters[] = $quality;
}
//call_user_func_array($this->_getCallback('output'), $functionParameters);
$source_file = $this->_fileSrcPath.'/'.$this->_fileSrcName;
$image_info = getimagesize($source_file);
$im = new Imagick();
$im->readImage($source_file);
//check to see if image needs to be resized (eg. thumbnails)
if ($image_info[0] != $this->_imageSrcWidth) {
$im->thumbnailImage($this->_imageSrcWidth, $this->_imageSrcHeight);
}
$im->writeImage($fileName);
}
public function display()
{
header("Content-type: ".$this->getMimeType());
call_user_func($this->_getCallback('output'), $this->_imageHandler);
}
/**
* Obtain function name, basing on image type and callback type
*
* #param string $callbackType
* #param int $fileType
* #return string
* #throws Exception
*/
private function _getCallback($callbackType, $fileType = null, $unsupportedText = 'Unsupported image format.')
{
if (null === $fileType) {
$fileType = $this->_fileType;
}
if (empty(self::$_callbacks[$fileType])) {
throw new Exception($unsupportedText);
}
if (empty(self::$_callbacks[$fileType][$callbackType])) {
throw new Exception('Callback not found.');
}
return self::$_callbacks[$fileType][$callbackType];
}
private function _fillBackgroundColor(&$imageResourceTo)
{
// try to keep transparency, if any
if ($this->_keepTransparency) {
$isAlpha = false;
$transparentIndex = $this->_getTransparency($this->_imageHandler, $this->_fileType, $isAlpha);
try {
// fill truecolor png with alpha transparency
if ($isAlpha) {
if (!imagealphablending($imageResourceTo, false)) {
throw new Exception('Failed to set alpha blending for PNG image.');
}
$transparentAlphaColor = imagecolorallocatealpha($imageResourceTo, 0, 0, 0, 127);
if (false === $transparentAlphaColor) {
throw new Exception('Failed to allocate alpha transparency for PNG image.');
}
if (!imagefill($imageResourceTo, 0, 0, $transparentAlphaColor)) {
throw new Exception('Failed to fill PNG image with alpha transparency.');
}
if (!imagesavealpha($imageResourceTo, true)) {
throw new Exception('Failed to save alpha transparency into PNG image.');
}
return $transparentAlphaColor;
}
// fill image with indexed non-alpha transparency
elseif (false !== $transparentIndex) {
$transparentColor = false;
if ($transparentIndex >=0 && $transparentIndex <= imagecolorstotal($this->_imageHandler)) {
list($r, $g, $b) = array_values(imagecolorsforindex($this->_imageHandler, $transparentIndex));
$transparentColor = imagecolorallocate($imageResourceTo, $r, $g, $b);
}
if (false === $transparentColor) {
throw new Exception('Failed to allocate transparent color for image.');
}
if (!imagefill($imageResourceTo, 0, 0, $transparentColor)) {
throw new Exception('Failed to fill image with transparency.');
}
imagecolortransparent($imageResourceTo, $transparentColor);
return $transparentColor;
}
}
catch (Exception $e) {
// fallback to default background color
}
}
list($r, $g, $b) = $this->_backgroundColor;
$color = imagecolorallocate($imageResourceTo, $r, $g, $b);
if (!imagefill($imageResourceTo, 0, 0, $color)) {
throw new Exception("Failed to fill image background with color {$r} {$g} {$b}.");
}
return $color;
}
/**
* Gives true for a PNG with alpha, false otherwise
*
* #param string $fileName
* #return boolean
*/
public function checkAlpha($fileName)
{
return ((ord(file_get_contents($fileName, false, null, 25, 1)) & 6) & 4) == 4;
}
private function _getTransparency($imageResource, $fileType, &$isAlpha = false, &$isTrueColor = false)
{
$isAlpha = false;
$isTrueColor = false;
// assume that transparency is supported by gif/png only
if ((IMAGETYPE_GIF === $fileType) || (IMAGETYPE_PNG === $fileType)) {
// check for specific transparent color
$transparentIndex = imagecolortransparent($imageResource);
if ($transparentIndex >= 0) {
return $transparentIndex;
}
// assume that truecolor PNG has transparency
elseif (IMAGETYPE_PNG === $fileType) {
$isAlpha = $this->checkAlpha($this->_fileName);
$isTrueColor = true;
return $transparentIndex; // -1
}
}
if (IMAGETYPE_JPEG === $fileType) {
$isTrueColor = true;
}
return false;
}
/**
* Change the image size
*
* #param int $frameWidth
* #param int $frameHeight
*/
public function resize($frameWidth = null, $frameHeight = null)
{
if (empty($frameWidth) && empty($frameHeight)) {
throw new Exception('Invalid image dimensions.');
}
// calculate lacking dimension
if (!$this->_keepFrame) {
if (null === $frameWidth) {
$frameWidth = round($frameHeight * ($this->_imageSrcWidth / $this->_imageSrcHeight));
}
elseif (null === $frameHeight) {
$frameHeight = round($frameWidth * ($this->_imageSrcHeight / $this->_imageSrcWidth));
}
}
else {
if (null === $frameWidth) {
$frameWidth = $frameHeight;
}
elseif (null === $frameHeight) {
$frameHeight = $frameWidth;
}
}
// define coordinates of image inside new frame
$srcX = 0;
$srcY = 0;
$dstX = 0;
$dstY = 0;
$dstWidth = $frameWidth;
$dstHeight = $frameHeight;
if ($this->_keepAspectRatio) {
// do not make picture bigger, than it is, if required
if ($this->_constrainOnly) {
if (($frameWidth >= $this->_imageSrcWidth) && ($frameHeight >= $this->_imageSrcHeight)) {
$dstWidth = $this->_imageSrcWidth;
$dstHeight = $this->_imageSrcHeight;
}
}
// keep aspect ratio
if ($this->_imageSrcWidth / $this->_imageSrcHeight >= $frameWidth / $frameHeight) {
$dstHeight = round(($dstWidth / $this->_imageSrcWidth) * $this->_imageSrcHeight);
} else {
$dstWidth = round(($dstHeight / $this->_imageSrcHeight) * $this->_imageSrcWidth);
}
}
// define position in center (TODO: add positions option)
$dstY = round(($frameHeight - $dstHeight) / 2);
$dstX = round(($frameWidth - $dstWidth) / 2);
// get rid of frame (fallback to zero position coordinates)
if (!$this->_keepFrame) {
$frameWidth = $dstWidth;
$frameHeight = $dstHeight;
$dstY = 0;
$dstX = 0;
}
// create new image
$isAlpha = false;
$isTrueColor = false;
$this->_getTransparency($this->_imageHandler, $this->_fileType, $isAlpha, $isTrueColor);
if ($isTrueColor) {
$newImage = imagecreatetruecolor($frameWidth, $frameHeight);
}
else {
$newImage = imagecreate($frameWidth, $frameHeight);
}
// fill new image with required color
$this->_fillBackgroundColor($newImage);
// resample source image and copy it into new frame
imagecopyresampled(
$newImage,
$this->_imageHandler,
$dstX, $dstY,
$srcX, $srcY,
$dstWidth, $dstHeight,
$this->_imageSrcWidth, $this->_imageSrcHeight
);
$this->_imageHandler = $newImage;
$this->refreshImageDimensions();
$this->_resized = true;
}
public function rotate($angle)
{
/*
$isAlpha = false;
$backgroundColor = $this->_getTransparency($this->_imageHandler, $this->_fileType, $isAlpha);
list($r, $g, $b) = $this->_backgroundColor;
if ($isAlpha) {
$backgroundColor = imagecolorallocatealpha($this->_imageHandler, 0, 0, 0, 127);
}
elseif (false === $backgroundColor) {
$backgroundColor = imagecolorallocate($this->_imageHandler, $r, $g, $b);
}
$this->_imageHandler = imagerotate($this->_imageHandler, $angle, $backgroundColor);
//*/
$this->_imageHandler = imagerotate($this->_imageHandler, $angle, $this->imageBackgroundColor);
$this->refreshImageDimensions();
}
public function watermark($watermarkImage, $positionX=0, $positionY=0, $watermarkImageOpacity=30, $repeat=false)
{
list($watermarkSrcWidth, $watermarkSrcHeight, $watermarkFileType, ) = getimagesize($watermarkImage);
$this->_getFileAttributes();
$watermark = call_user_func($this->_getCallback(
'create',
$watermarkFileType,
'Unsupported watermark image format.'
), $watermarkImage);
$merged = false;
if ($this->getWatermarkWidth() &&
$this->getWatermarkHeigth() &&
($this->getWatermarkPosition() != self::POSITION_STRETCH)
) {
$newWatermark = imagecreatetruecolor($this->getWatermarkWidth(), $this->getWatermarkHeigth());
imagealphablending($newWatermark, false);
$col = imagecolorallocate($newWatermark, 255, 255, 255);
imagecolortransparent($newWatermark, $col);
imagefilledrectangle($newWatermark, 0, 0, $this->getWatermarkWidth(), $this->getWatermarkHeigth(), $col);
imagealphablending($newWatermark, true);
imageSaveAlpha($newWatermark, true);
imagecopyresampled(
$newWatermark,
$watermark,
0, 0, 0, 0,
$this->getWatermarkWidth(), $this->getWatermarkHeigth(),
imagesx($watermark), imagesy($watermark)
);
$watermark = $newWatermark;
}
if( $this->getWatermarkPosition() == self::POSITION_TILE ) {
$repeat = true;
} elseif( $this->getWatermarkPosition() == self::POSITION_STRETCH ) {
$newWatermark = imagecreatetruecolor($this->_imageSrcWidth, $this->_imageSrcHeight);
imagealphablending($newWatermark, false);
$col = imagecolorallocate($newWatermark, 255, 255, 255);
imagecolortransparent($newWatermark, $col);
imagefilledrectangle($newWatermark, 0, 0, $this->_imageSrcWidth, $this->_imageSrcHeight, $col);
imagealphablending($newWatermark, true);
imageSaveAlpha($newWatermark, true);
imagecopyresampled(
$newWatermark,
$watermark,
0, 0, 0, 0,
$this->_imageSrcWidth, $this->_imageSrcHeight,
imagesx($watermark), imagesy($watermark)
);
$watermark = $newWatermark;
} elseif( $this->getWatermarkPosition() == self::POSITION_CENTER ) {
$positionX = ($this->_imageSrcWidth/2 - imagesx($watermark)/2);
$positionY = ($this->_imageSrcHeight/2 - imagesy($watermark)/2);
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} elseif( $this->getWatermarkPosition() == self::POSITION_TOP_RIGHT ) {
$positionX = ($this->_imageSrcWidth - imagesx($watermark));
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} elseif( $this->getWatermarkPosition() == self::POSITION_TOP_LEFT ) {
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} elseif( $this->getWatermarkPosition() == self::POSITION_BOTTOM_RIGHT ) {
$positionX = ($this->_imageSrcWidth - imagesx($watermark));
$positionY = ($this->_imageSrcHeight - imagesy($watermark));
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} elseif( $this->getWatermarkPosition() == self::POSITION_BOTTOM_LEFT ) {
$positionY = ($this->_imageSrcHeight - imagesy($watermark));
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
}
if( $repeat === false && $merged === false ) {
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} else {
$offsetX = $positionX;
$offsetY = $positionY;
while( $offsetY <= ($this->_imageSrcHeight+imagesy($watermark)) ) {
while( $offsetX <= ($this->_imageSrcWidth+imagesx($watermark)) ) {
imagecopymerge(
$this->_imageHandler,
$watermark,
$offsetX, $offsetY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
$offsetX += imagesx($watermark);
}
$offsetX = $positionX;
$offsetY += imagesy($watermark);
}
}
imagedestroy($watermark);
$this->refreshImageDimensions();
}
public function crop($top=0, $left=0, $right=0, $bottom=0)
{
if( $left == 0 && $top == 0 && $right == 0 && $bottom == 0 ) {
return;
}
$newWidth = $this->_imageSrcWidth - $left - $right;
$newHeight = $this->_imageSrcHeight - $top - $bottom;
$canvas = imagecreatetruecolor($newWidth, $newHeight);
if ($this->_fileType == IMAGETYPE_PNG) {
$this->_saveAlpha($canvas);
}
imagecopyresampled(
$canvas,
$this->_imageHandler,
0, 0, $left, $top,
$newWidth, $newHeight,
$newWidth, $newHeight
);
$this->_imageHandler = $canvas;
$this->refreshImageDimensions();
}
public function checkDependencies()
{
foreach( $this->_requiredExtensions as $value ) {
if( !extension_loaded($value) ) {
throw new Exception("Required PHP extension '{$value}' was not loaded.");
}
}
}
private function refreshImageDimensions()
{
$this->_imageSrcWidth = imagesx($this->_imageHandler);
$this->_imageSrcHeight = imagesy($this->_imageHandler);
}
function __destruct()
{
#imagedestroy($this->_imageHandler);
}
/*
* Fixes saving PNG alpha channel
*/
private function _saveAlpha($imageHandler)
{
$background = imagecolorallocate($imageHandler, 0, 0, 0);
ImageColorTransparent($imageHandler, $background);
imagealphablending($imageHandler, false);
imagesavealpha($imageHandler, true);
}
}
Have you tried the hackathon magento imagemagick enabler?
[https://github.com/magento-hackathon/Perfect_Watermarks][1]
I am going to test this in a minute, so this suggestion is absolutly untested at the moment.

Fast resize picture tool/script

I have a lot of images (500,000 +) in a folder on the server organized by date. I made a PHP script to copy and crop each JPG file on a subfolder (thumb), but it's very slow since PHP doesn't support multithreading.
I want advice on how to proceed. Is Python a good option for this? Is there a good tool, or how can I improve my resize function?
You can also take a look to my PHP Code
You can do it in PHP without any problem, simulating threads instead of using them directly. Actually, PHP doesn't have native threads (you can eventuallĀ„ use libraries but that's not very useful in your case).
In your code, instead of calling :
static::Crop($file,$destination,$tn_w = 300,$tn_h =200,$quality = 100,$wmsource = false);
Why not doing :
$array = array($file, $destination, $tn_w = 300, $tn_h = 200, $quality = 100, $wmsource = 0);
$command = "/usr/bin/php crop.php";
foreach ($array as $arg)
{
$command .= ' ' . escapeshellarg($arg);
}
exec("$command &"); // note the & which release your execution
usleep(100000);
And you put your cropping function inside crop.php, and then call it like :
list($exec, $file, $destination, $tn_w, $tn_h, $quality, $wmsource) = $argv;
static::Crop($file,$destination,$tn_w = 300,$tn_h =200,$quality = 100,$wmsource = false);
This will do the job.
You can also simulate mutexes using a file if you want to avoid usleep and control how many crops are running at once, that's really up to you. You definitely can do such work in PHP.
But php cgi support multithreading. Why not using exec()? Or you can use a shell script and for the conversion php cgi?
by Use This class
<?php
class thumbnail_images {
// get
var $PathImgOld;
var $PathImgNew;
var $NewWidth;
var $NewHeight;
// tmp
var $mime;
function imagejpeg_new ($NewImg,$path_img) {
if ($this->mime == 'image/jpeg' or $this->mime == 'image/pjpeg') imagejpeg($NewImg,$path_img);
elseif ($this->mime == 'image/gif') imagegif($NewImg, $path_img);
elseif ($this->mime == 'image/png') imagepng($NewImg, $path_img);
else return(false);
return(true);
}
function imagecreatefromjpeg_new($path_img) {
if ($this->mime == 'image/jpeg' or $this->mime == 'image/pjpeg') $OldImg = imagecreatefromjpeg($path_img);
elseif ($this->mime == 'image/gif') $OldImg = imagecreatefromgif($path_img);
elseif ($this->mime == 'image/png') $OldImg = imagecreatefrompng($path_img);
else return(false);
return($OldImg);
}
function create_thumbnail_images() {
$PathImgOld = $this->PathImgOld;
$PathImgNew = $this->PathImgNew;
$NewWidth = $this->NewWidth;
$NewHeight = $this->NewHeight;
$Oldsize = #getimagesize($PathImgOld);
$this->mime = $Oldsize['mime'];
$OldWidth = $Oldsize[0];
$OldHeight = $Oldsize[1];
if ($NewHeight == '' and $NewWidth != '') {
$NewHeight = ceil(($OldHeight * $NewWidth) / $OldWidth);
}
elseif ($NewWidth == '' and $NewHeight != '') {
$NewWidth = ceil(($OldWidth * $NewHeight) / $OldHeight);
}
elseif ($NewHeight == '' and $NewWidth == '') {
return(false);
}
$OldHeight_castr = ceil(($OldWidth * $NewHeight) / $NewWidth);
$castr_bottom = ($OldHeight - $OldHeight_castr) / 2;
$OldWidth_castr = ceil(($OldHeight * $NewWidth) / $NewHeight);
$castr_right = ($OldWidth - $OldWidth_castr) / 2;
if ($castr_bottom>0) {
$OldWidth_castr = $OldWidth;
$castr_right = 0;
}
elseif ($castr_right>0) {
$OldHeight_castr = $OldHeight;
$castr_bottom = 0;
}
else {
$OldWidth_castr = $OldWidth;
$OldHeight_castr = $OldHeight;
$castr_right = 0;
$castr_bottom = 0;
}
$OldImg = $this->imagecreatefromjpeg_new($PathImgOld);
if ($OldImg) {
$NewImg_castr = imagecreatetruecolor($OldWidth_castr, $OldHeight_castr);
if ($NewImg_castr) {
imagecopyresampled($NewImg_castr, $OldImg, 0, 0, $castr_right, $castr_bottom, $OldWidth_castr, $OldHeight_castr, $OldWidth_castr, $OldHeight_castr);
$NewImg = imagecreatetruecolor($NewWidth, $NewHeight);
if ($NewImg) {
imagecopyresampled($NewImg, $NewImg_castr, 0, 0, 0, 0, $NewWidth, $NewHeight, $OldWidth_castr, $OldHeight_castr);
imagedestroy($NewImg_castr);
imagedestroy($OldImg);
if (!$this->imagejpeg_new($NewImg, $PathImgNew)) return (false);
imagedestroy($NewImg);
}
}
}
else {
return(false);
}
return(true);
}
}
?>
Now use it
$width = $_REQUEST['img_width'];
$height = $_REQUEST['img_height'];
// example
$obj_img = new thumbnail_images();
$obj_img->PathImgOld = 'Old_image.jpg'; // Image for resize
$obj_img->PathImgNew = 'my_image_new_formSubURLkki.jpg'; // New Image Path
$obj_img->NewWidth = $width;
$obj_img->NewHeight = $height;
if (!$obj_img->create_thumbnail_images()) echo "error";
else {
echo 'Image Maked andsave in directory';
}

Delay a while loop in PHP to prevent memory exhaustion?

I have a pretty simple image resize script that loops through 1000 folders, with different amounts of images in each folder. On my testing server, there aren't a lot of images, so it runs fine...but live with about 100K images...it will run into the memory problem. The php memory is already set to 384M, but i'd rather have the script maybe only process 10 folders at a time, stop for a bit, then start again. How can I do that within the while loop? use the sleep function maybe?
Here it is...
class DevTestHelper {
//This will Go through all full size images and resize images into requested folder
function resizeGalleryImages($destFolder, $width, $height, $isCrop = false) {
$count = 1000;
$source = JPATH_SITE."/images/gallery/full";
$dest = JPATH_SITE."/images/gallery/".$destFolder;
echo 'Processing Images<br>';
//Loop through all 1000 folders 0 to 999 in the /full dir
for($i=0; $i < $count;$i++) {
$iPath = $source.'/'.$i;
if(is_dir($iPath)) {
$h = opendir($iPath);
//Loop through all the files in numbered folder
while ($entry = readdir($h)) {
//only read files
if ($entry != "." && $entry != ".." && !is_dir($entry)) {
$img = new GImage($source.'/'.$i.'/'.$entry);
$tmp = $img->resize($width, $height, true, 3);
if($isCrop) {
$tmpWidth = $tmp->getWidth();
$tmpHeight = $tmp->getHeight();
$xOffset = ($tmpWidth - $width) / 2;
$yOffset = ($tmpHeight - $height) / 2;
$tmp->crop($width, $height, $xOffset, $yOffset, false, 3);
}
$destination = $dest.'/'.$i.'/'.$entry;
if(!$tmp->toFile($destination)) {
echo 'error in creating resized image at: '.$destination.'<br>';
}
flush();
ob_flush();
sleep(10);
echo $entry ;
//echo $entry.'<br>';
}
}
echo 'Processed: '.$i.' Folder<br>';
}
}
Thanks for any suggestions.
/**
* Class to manipulate an image.
*
* #package Gallery.Libraries
* #subpackage Media
* #version 1.0
*/
class GImage extends JObject
{
/**
* The image handle
*
* #access private
* #var resource
*/
var $_handle = null;
/**
* The source image path
*
* #access private
* #var string
*/
var $_path = null;
var $_support = array();
/**
* Constructor
*
* #access public
* #return void
* #since 1.0
*/
function __construct($source=null)
{
// First we test if dependencies are met.
if (!GImageHelper::test()) {
$this->setError('Unmet Dependencies');
return false;
}
// Determine which image types are supported by GD.
$info = gd_info();
if ($info['JPG Support']) {
$this->_support['JPG'] = true;
}
if ($info['GIF Create Support']) {
$this->_support['GIF'] = true;
}
if ($info['PNG Support']) {
$this->_support['PNG'] = true;
}
// If the source input is a resource, set it as the image handle.
if ((is_resource($source) && get_resource_type($source) == 'gd')) {
$this->_handle = &$source;
} elseif (!empty($source) && is_string($source)) {
// If the source input is not empty, assume it is a path and populate the image handle.
//Andy - Big freaking cockroach: if file is wrong type or doesn't even exist the error is not handled.
$this->loadFromFile($source);
}
}
function crop($width, $height, $left, $top, $createNew = true, $scaleMethod = JXIMAGE_SCALE_INSIDE)
{
// Make sure the file handle is valid.
if ((!is_resource($this->_handle) || get_resource_type($this->_handle) != 'gd')) {
$this->setError('Invalid File Handle');
return false;
}
// Sanitize width.
$width = ($width === null) ? $height : $width;
if (preg_match('/^[0-9]+(\.[0-9]+)?\%$/', $width)) {
$width = intval(round($this->getWidth() * floatval(str_replace('%', '', $width)) / 100));
} else {
$width = intval(round(floatval($width)));
}
// Sanitize height.
$height = ($height === null) ? $width : $height;
if (preg_match('/^[0-9]+(\.[0-9]+)?\%$/', $height)) {
$height = intval(round($this->getHeight() * floatval(str_replace('%', '', $height)) / 100));
} else {
$height = intval(round(floatval($height)));
}
// Sanitize left.
$left = intval(round(floatval($left)));
// Sanitize top.
$top = intval(round(floatval($top)));
// Create the new truecolor image handle.
$handle = imagecreatetruecolor($width, $height);
// Allow transparency for the new image handle.
imagealphablending($handle, false);
imagesavealpha($handle, true);
if ($this->isTransparent()) {
// Get the transparent color values for the current image.
$rgba = imageColorsForIndex($this->_handle, imagecolortransparent($this->_handle));
$color = imageColorAllocate($this->_handle, $rgba['red'], $rgba['green'], $rgba['blue']);
// Set the transparent color values for the new image.
imagecolortransparent($handle, $color);
imagefill($handle, 0, 0, $color);
imagecopyresized(
$handle,
$this->_handle,
0, 0,
$left,
$top,
$width,
$height,
$width,
$height
);
} else {
imagecopyresampled(
$handle,
$this->_handle,
0, 0,
$left,
$top,
$width,
$height,
$width,
$height
);
}
// If we are cropping to a new image, create a new GImage object.
if ($createNew)
{
// Create the new GImage object for the new truecolor image handle.
$new = new GImage($handle);
return $new;
} else
{
// Swap out the current handle for the new image handle.
$this->_handle = &$handle;
return true;
}
}
function filter($type)
{
// Initialize variables.
$name = preg_replace('#[^A-Z0-9_]#i', '', $type);
$className = 'GImageFilter_'.ucfirst($name);
if (!class_exists($className))
{
jimport('joomla.filesystem.path');
if ($path = JPath::find(GImageFilter::addIncludePath(), strtolower($name).'.php'))
{
require_once $path;
if (!class_exists($className)) {
$this->setError($className.' not found in file.');
return false;
}
}
else {
$this->setError($className.' not supported. File not found.');
return false;
}
}
$instance = new $className;
if (is_callable(array($instance, 'execute')))
{
// Setup the arguments to call the filter execute method.
$args = func_get_args();
array_shift($args);
array_unshift($args, $this->_handle);
// Call the filter execute method.
$return = call_user_func_array(array($instance, 'execute'), $args);
// If the filter failed, proxy the error and return false.
if (!$return) {
$this->setError($instance->getError());
return false;
}
return true;
}
else {
$this->setError($className.' not valid.');
return false;
}
}
function getHeight()
{
return imagesy($this->_handle);
}
function getWidth()
{
return imagesx($this->_handle);
}
function isTransparent()
{
// Make sure the file handle is valid.
if ((!is_resource($this->_handle) || get_resource_type($this->_handle) != 'gd')) {
$this->setError('Invalid File Handle');
return false;
}
return (imagecolortransparent($this->_handle) >= 0);
}
function loadFromFile($path)
{
// Make sure the file exists.
if (!JFile::exists($path)) {
$this->setError('File Does Not Exist');
return false;
}
// Get the image properties.
$properties = GImageHelper::getProperties($path);
if (!$properties) {
return false;
}
// Attempt to load the image based on the MIME-Type
switch ($properties->get('mime'))
{
case 'image/gif':
// Make sure the image type is supported.
if (empty($this->_support['GIF'])) {
$this->setError('File Type Not Supported');
return false;
}
// Attempt to create the image handle.
$handle = #imagecreatefromgif($path);
if (!is_resource($handle)) {
$this->setError('Unable To Process Image');
return false;
}
$this->_handle = &$handle;
break;
case 'image/jpeg':
// Make sure the image type is supported.
if (empty($this->_support['JPG'])) {
$this->setError('File Type Not Supported');
return false;
}
// Attempt to create the image handle.
$handle = #imagecreatefromjpeg($path);
if (!is_resource($handle)) {
$this->setError('Unable To Process Image');
return false;
}
$this->_handle = &$handle;
break;
case 'image/png':
// Make sure the image type is supported.
if (empty($this->_support['PNG'])) {
$this->setError('File Type Not Supported');
return false;
}
// Attempt to create the image handle.
$handle = #imagecreatefrompng($path);
if (!is_resource($handle)) {
$this->setError('Unable To Process Image');
return false;
}
$this->_handle = &$handle;
break;
default:
$this->setError('File Type Not Supported');
return false;
break;
}
// Set the filesystem path to the source image.
$this->_path = $path;
return true;
}
function resize($width, $height, $createNew = true, $scaleMethod = JXIMAGE_SCALE_INSIDE)
{
// Make sure the file handle is valid.
if ((!is_resource($this->_handle) || get_resource_type($this->_handle) != 'gd')) {
$this->setError('Invalid File Handle');
return false;
}
// Prepare the dimensions for the resize operation.
$dimensions = $this->_prepareDimensions($width, $height, $scaleMethod);
if (empty($dimensions)) {
return false;
}
//var_dump($dimensions);
// Create the new truecolor image handle.
$handle = imagecreatetruecolor($dimensions['width'], $dimensions['height']);
// Allow transparency for the new image handle.
imagealphablending($handle, false);
imagesavealpha($handle, true);
if ($this->isTransparent()) {
// Get the transparent color values for the current image.
$rgba = imageColorsForIndex($this->_handle, imagecolortransparent($this->_handle));
$color = imageColorAllocate($this->_handle, $rgba['red'], $rgba['green'], $rgba['blue']);
// Set the transparent color values for the new image.
imagecolortransparent($handle, $color);
imagefill($handle, 0, 0, $color);
imagecopyresized(
$handle,
$this->_handle,
0, 0, 0, 0,
$dimensions['width'],
$dimensions['height'],
$this->getWidth(),
$this->getHeight()
);
} else {
imagecopyresampled(
$handle,
$this->_handle,
0, 0, 0, 0,
$dimensions['width'],
$dimensions['height'],
$this->getWidth(),
$this->getHeight()
);
}
// If we are resizing to a new image, create a new GImage object.
if ($createNew)
{
// Create the new GImage object for the new truecolor image handle.
$new = new GImage($handle);
return $new;
} else
{
// Swap out the current handle for the new image handle.
$this->_handle = &$handle;
return true;
}
}
function toFile($path, $type = IMAGETYPE_JPEG, $options=array())
{
switch ($type)
{
case IMAGETYPE_GIF:
$ret = imagegif($this->_handle, $path);
break;
case IMAGETYPE_PNG:
$ret = imagepng($this->_handle, $path, (array_key_exists('quality', $options)) ? $options['quality'] : 0);
break;
case IMAGETYPE_JPEG:
default:
$ret = imagejpeg($this->_handle, $path, (array_key_exists('quality', $options)) ? $options['quality'] : 100);
break;
}
return $ret;
}
function display() {
//header('Content-type: image/jpeg');
imagejpeg($this->_handle,'',100);
}
function _prepareDimensions($width, $height, $scaleMethod)
{
// Sanitize width.
$width = ($width === null) ? $height : $width;
if (preg_match('/^[0-9]+(\.[0-9]+)?\%$/', $width)) {
$width = intval(round($this->getWidth() * floatval(str_replace('%', '', $width)) / 100));
} else {
$width = intval(round(floatval($width)));
}
// Sanitize height.
$height = ($height === null) ? $width : $height;
if (preg_match('/^[0-9]+(\.[0-9]+)?\%$/', $height)) {
$height = intval(round($this->getHeight() * floatval(str_replace('%', '', $height)) / 100));
} else {
$height = intval(round(floatval($height)));
}
$dimensions = array();
if ($scaleMethod == JXIMAGE_SCALE_FILL)
{
$dimensions['width'] = $width;
$dimensions['height'] = $height;
}
elseif ($scaleMethod == JXIMAGE_SCALE_INSIDE || $scaleMethod == JXIMAGE_SCALE_OUTSIDE)
{
$rx = $this->getWidth() / $width;
$ry = $this->getHeight() / $height;
if ($scaleMethod == JXIMAGE_SCALE_INSIDE)
$ratio = ($rx > $ry) ? $rx : $ry;
else
$ratio = ($rx < $ry) ? $rx : $ry;
$dimensions['width'] = round($this->getWidth() / $ratio);
$dimensions['height'] = round($this->getHeight() / $ratio);
}
else {
$this->setError('Invalid Fit Option');
return false;
}
return $dimensions;
}
}
class GImageFilter extends JObject
{
/**
* Add a directory where GImage should search for filters. You may
* either pass a string or an array of directories.
*
* #access public
* #param string A path to search.
* #return array An array with directory elements
* #since 1.5
*/
function addIncludePath($path='')
{
static $paths;
if (!isset($paths)) {
$paths = array(dirname(__FILE__).'/image');
}
// force path to array
settype($path, 'array');
// loop through the path directories
foreach ($path as $dir)
{
if (!empty($dir) && !in_array($dir, $paths)) {
array_unshift($paths, JPath::clean( $dir ));
}
}
return $paths;
}
function execute()
{
$this->setError('Method Not Implemented');
return false;
}
}
class GImageHelper
{
function getProperties($path)
{
// Initialize the path variable.
$path = (empty($path)) ? $this->_path : $path;
// Make sure the file exists.
if (!JFile::exists($path)) {
$e = new JException('File Does Not Exist');
return false;
}
// Get the image file information.
$info = #getimagesize($path);
if (!$info) {
$e = new JException('Unable To Get Image Size');
return false;
}
// Build the response object.
$result = new JObject;
$result->set('width', $info[0]);
$result->set('height', $info[1]);
$result->set('type', $info[2]);
$result->set('attributes', $info[3]);
$result->set('bits', #$info['bits']);
$result->set('channels', #$info['channels']);
$result->set('mime', $info['mime']);
return $result;
}
function test()
{
return (function_exists('gd_info') && function_exists('imagecreatetruecolor'));
}
}
It looks to me like you have a memory leak, when creating $img using new GImage it will likely be reading the image into memory which you never release.
You take a copy of the resized image:
$tmp = $img->resize($width, $height, true, 3);
but next time around the loop you create a new GImage again using the $img variable.
Does GIMage have some kind of close or cleanup function? If so, do that at the end of each loop before you call new GImage again.
closeGImage($img);
UPDATE:
In response to your updated question it looks like you can do one of two things:
Change the 3rd parameter of $img->resize() to false as this will stop a new GImage being created on image resize.
Write your own image destroy function as part of the GImage class. Because GImage is based upon the GD library you can use the imagedestroy function, see here.
UPDATE 2:
Ok, so following on from your comment... What you'll want to do to create a destroy image function is inside the GImage class, add the following function:
function closeImage()
{
imagedestroy($this->_handle);
}
Now at the bottom of the for loop in devtest.php add a call to this function:
...
ob_flush();
sleep(10);
echo $entry ;
$img->closeImage();
...
Try using sleep or usleep to avoid CPU overload.
Maybe GImage have a dispose() or destroy() method to avoid memory retention.
You could also do batch processing.

PHP HELP: (the image "bla bla" cannot be displayed because it contains errors

Im facing a very annoying problem in PHP when Im trying to watermark the full size images on my website. The watermark was working fine for weeks but all the sudden it started showing this error : the image "bla bla" cannot be displayed because it contains errors
I checked everything and everything seems to be working just fine! I'm stuck and I dont know what to do.
Here is my watermarking php file:
require_once "maincore.php";
if (isset($_GET['photo_id']) && isnum($_GET['photo_id'])) {
$result = dbquery("SELECT td.*, tc.* FROM ".DB_PRODUCTS." td LEFT JOIN ".DB_PRODUCT_CATS." tc ON td.product_cat=tc.cat_id WHERE product_id='".$_GET['photo_id']."'");
$data = dbarray($result);
define("PHOTODIR", BASEDIR."downloads/images/");
$parts = explode(".", $data['product_image']);
$wm_file1 = $parts[0]."_w1.".$parts[1];
$wm_file2 = $parts[0]."_w2.".$parts[1];
if (!isset($_GET['full'])) {
$wm_file = PHOTODIR.$wm_file1;
} else {
$wm_file = PHOTODIR.$wm_file2;
}
header("Content-type: image/jpg");
$img = PHOTODIR.$data['product_image'];
$cop = BASEDIR.$settings['photo_watermark_image'];
if (preg_match("/.jpg/i", strtolower($img)) || preg_match("/.jpeg/i", strtolower($img))) {
$image = imagecreatefromjpeg($img);
} else if (preg_match("/.png/i", strtolower($img))) {
$image = imagecreatefrompng($img);
} else if (preg_match("/.gif/i", strtolower($img))) {
$image = imagecreatefromgif($img);
$sizeX = imagesx($image);
$sizeY = imagesy($image);
$image_tmp = imagecreatetruecolor($sizeX, $sizeY);
$ica = imagecolorallocate($image_tmp, 255, 255, 255);
imagefill($image_tmp, 0, 0, $ica);
if ($settings['thumb_compression'] == "gd2") {
imagecopyresampled($image_tmp, $image, 0, 0, 0, 0, $sizeX, $sizeY, $sizeX, $sizeY);
} else {
imagecopyresized($image_tmp, $image, 0, 0, 0, 0, $sizeX, $sizeY, $sizeX, $sizeY);
}
$tmp = PHOTODIR.md5(time().$img).'.tmp';
imagejpeg($image_tmp, $tmp);
imagedestroy($image_tmp);
$image = imagecreatefromjpeg($tmp);
unlink($tmp);
}
if (file_exists($cop) && preg_match("/.png/i", strtolower($cop)) && $settings['photo_watermark']) {
$image2 = false;
$image_dim_x = imagesx($image);
$image_dim_y = imagesy($image);
$copyright = imagecreatefrompng($cop);
$copyright_dim_x = imagesx($copyright);
$copyright_dim_y = imagesy($copyright);
$where_x = $image_dim_x - $copyright_dim_x - 5;
$where_y = $image_dim_y - $copyright_dim_y - 5;
imagecopy ($image, $copyright, $where_x, $where_y, 0, 0, $copyright_dim_x, $copyright_dim_y);
$thumb_w = 0; $thumb_h = 0;
if (!isset($_GET['full'])) {
if ($image_dim_x > $settings['photo_w'] || $image_dim_y > $settings['photo_h']) {
if ($image_dim_x $image_dim_y) {
$thumb_w = $settings['photo_w'];
$thumb_h = round(($image_dim_y * $settings['photo_w']) / $image_dim_x);
} else {
$thumb_w = $settings['photo_w'];
$thumb_h = $settings['photo_h'];
}
} else {
$thumb_w = $image_dim_x;
$thumb_h = $image_dim_y;
}
$image2 = imagecreatetruecolor($thumb_w, $thumb_h);
if ($settings['thumb_compression'] == "gd2") {
imagecopyresampled($image2, $image, 0, 0, 0, 0, $thumb_w, $thumb_h, $image_dim_x, $image_dim_y);
} else {
imagecopyresized($image2, $image, 0, 0, 0, 0, $thumb_w, $thumb_h, $image_dim_x, $image_dim_y);
}
imagedestroy($image);
}
}
//create image
if ($settings['photo_watermark_save']) { imagejpeg(($image2 ? $image2 : $image), $wm_file); }
imagejpeg((isset($image2) && $image2 ? $image2 : $image));
imagedestroy((isset($image2) && $image2 ? $image2 : $image));
if (isset($copyright) && is_resource($copyright)) { ImageDestroy($copyright); }
} else {
redirect("index.php");
}
Please Help ME! Thank you!
Is php.ini set with display_errors turned on? If so, your code may be throwing a warning or notice which is getting incorporated into the binary image data and corrupting it.
Check your PHP error log for new entries.
Another possibility is that an include file is outputting whitespace by having multiple blank lines in the bottom below the closing PHP tag.

Categories