[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 570
  • Last Modified:

php crop after resize

Hi fellow experts. Im in some sort of twilight zone for more then a day and I need Your help.
I need to upload image with some width and height and crop a part with new width and new height. For example:

original img (600x374)

I need two thumbs, one with 100x100 and one with 200x100.
What I did so far is to resize original image to 160x100 and 200x124 so I can keep aspect ratio, but now I want to crop 100x100 and 200x100 respectively. Is that even possible with one imagecopyresampled command or I need two of them (first one to resize, second one to crop it).

Look at my code below to see what I achieved so far. Folder structure looks like this:

storage
|-images
  |-!100x100!
  |-!200x100!

Original img goes to images folder and thumbnails needs to go to !100x100! and !200x200! folders. So Im getting original coppied where it needs to, at 100x100 folder I get image with 160x100 and in 200x100 folder I get image with 200x124.

Thanks in advance.


//This stops SQL Injection in POST vars
	foreach ($_POST as $key => $value) {
		$$key = mysql_real_escape_string(stripslashes(htmlspecialchars(strip_tags($value))));
	}
	
	//This stops SQL Injection in GET vars
	foreach ($_GET as $key => $value) {
		$$key = mysql_real_escape_string(stripslashes(htmlspecialchars(strip_tags($value))));
	}
	
	$storage = "storage/" . $path;
	$contents = scandir($storage);
	$bad = array(".", "..");
    $items = array_diff($contents, $bad);
	
	foreach ($items as &$item)
	{
		if ((filetype($storage."/".$item) == "dir") && (utf8_substr($item,0,1) == "!") && (utf8_substr($item,-1) == "!"))
			//$sizes[] = array_filter(explode("x",utf8_substr($item,1,-1)));
			$item = array_filter(explode("x",utf8_substr($item,1,-1)));
	}
	
//	print_r($items);

	if (!empty($_FILES)) {
		$tempFile = $_FILES['Filedata']['tmp_name'];

		$targetPath = $storage . '/';

		$targetFile =  str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];

		move_uploaded_file($tempFile,$targetFile);
		echo "1";
		list($width, $height) = getimagesize($targetFile);
		
		$ratio = $width/$height;
		
		foreach ($items as &$item)
		{
			$newwidth = $item[0]; // This can be a set value or a percentage of original size ($width)
			$newheight = $item[1]; // This can be a set value or a percentage of original size ($height)
			
			if ($item[0] == $item[1])
			{
				if ($width > $height)
				{
					$newwidth = $item[1] * $ratio;
				}
				elseif ($width < $height)
				{
					$newheight = $item[0] / $ratio;
				}
			}
			elseif ($item[0] > $item[1])
			{
				$newheight = $item[0] / $ratio;
			}
			else
			{
				$newwidth = $item[1] * $ratio;
			}
				
			

			
			$thumb = imagecreatetruecolor($newwidth, $newheight);
			$source = imagecreatefromjpeg($targetFile);
			
			imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
			
			$itemFile = $storage . "/" . "!" . $item[0] . "x" . $item[1] . "!/" . $_FILES['Filedata']['name'];

			
			imagejpeg($thumb1, $itemFile, 100);

				echo "1";
		}

	}

Open in new window

0
R-Byter
Asked:
R-Byter
  • 5
  • 4
1 Solution
 
Marco GasiFreelancerCommented:
Sorry, but if you say towish to crop the two images, I understand you want to create a smaller image which captures only a portion of the original image. If this is right, you should use imagecopy() function, not imagecopyresampled(). In fact, if you wish to capture only a portion of original image you don't need to resample image because you don't reduce its size nor its quality.

But if you wish to give a smaller size to the entire image without regarding to the aspect ratio, then you have to use imagecopyresampled() function.

In both cases, you have to use two separate commands, because you give different parameters regarding width and height: 160 x 100 vs 100 x 100 and 200 x 124 vs 200 x 100.
0
 
Ray PaseurCommented:
Near line 66, et seq...

$thumb = imagecreatetruecolor($newwidth, $newheight);
...
imagejpeg($thumb1, $itemFile, 100);

It appears that $thumb1 is undefined in this script.
0
 
R-ByterAuthor Commented:
Well, I think imagecopy and imagecopyresampled works pretty much the same way, though imagecopyresampled  gives "smoother" images.
What I want is to capture a portion of original image reduced size.
So if I have a picture of some face 1000x500px, and I need a thumbnail of 100x100, it would look silly to take crop directly from image with original size because i would get one eye, part of hair... :)
The idea was to reduce the image in its size, keep aspect ratio, and then take a crop of reduced image. Most of the examples I found on the net create square thumbnails, it is pretty much easy to do it. Didnt found example which would take original image and create thumbnails with predefined width and height.
Thanks
0
[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

 
R-ByterAuthor Commented:
Thanks Ray I noticed that, my mistake. It should be:

imagejpeg($thumb, $itemFile, 100);



0
 
Ray PaseurCommented:
This seems to work for me.
RAY-temp-600x374.jpg
0
 
Ray PaseurCommented:
Here is the script that I used to process the test image.

There are a lot of ways to deal with the peripheral parts of this question.  Should the function return the image resource?  Or send the image into the browser output stream?  You can probably make those choices better for your application than I can.  The function as written stores the image on the file server.

HTH, ~Ray
<?php // RAY_resize_and_crop.php
error_reporting(E_ALL);

// RESIZE AN IMAGE PROPORTIONALLY AND CROP CENTERED

function resize_and_crop($original_image_url, $thumb_image_url, $thumb_w, $thumb_h, $quality=75)
{
    // ACQUIRE THE ORIGINAL IMAGE: http://us3.php.net/manual/en/function.imagecreatefromjpeg.php
    $original = imagecreatefromjpeg($original_image_url);
    if (!$original) return FALSE;

    // GET ORIGINAL IMAGE DIMENSIONS
    list($original_w, $original_h) = getimagesize($original_image_url);

    // RESIZE IMAGE AND PRESERVE PROPORTIONS KEEPING AS MUCH OF THE IMAGE AS POSSIBLE
    $thumb_w_resize = $thumb_w;
    $thumb_h_resize = $thumb_h;
    if ($original_w > $original_h)
    {
        $thumb_h_ratio  = $thumb_h / $original_h;
        $thumb_w_resize = (int)round($original_w * $thumb_h_ratio);
    }
    else
    {
        $thumb_w_ratio  = $thumb_w / $original_w;
        $thumb_h_resize = (int)round($original_h * $thumb_w_ratio);
    }
    if ($thumb_w_resize < $thumb_w)
    {
        $thumb_h_ratio  = $thumb_w / $thumb_w_resize;
        $thumb_h_resize = (int)round($thumb_h * $thumb_h_ratio);
        $thumb_w_resize = $thumb_w;
    }

    // CREATE THE PROPORTIONAL IMAGE RESOURCE
    $thumb = imagecreatetruecolor($thumb_w_resize, $thumb_h_resize);
    if (!imagecopyresampled($thumb, $original, 0,0,0,0, $thumb_w_resize, $thumb_h_resize, $original_w, $original_h)) return FALSE;

    // ACTIVATE THIS TO STORE THE INTERMEDIATE IMAGE
    // imagejpeg($thumb, 'RAY_temp_' . $thumb_w_resize . 'x' . $thumb_h_resize . '.jpg', 100);

    // CREATE THE CENTERED CROPPED IMAGE TO THE SPECIFIED DIMENSIONS
    $final = imagecreatetruecolor($thumb_w, $thumb_h);

    $thumb_w_offset = 0;
    $thumb_h_offset = 0;
    if ($thumb_w < $thumb_w_resize)
    {
        $thumb_w_offset = (int)round(($thumb_w_resize - $thumb_w) / 2);
    }
    else
    {
        $thumb_h_offset = (int)round(($thumb_h_resize - $thumb_h) / 2);
    }

    if (!imagecopy($final, $thumb, 0,0, $thumb_w_offset, $thumb_h_offset, $thumb_w_resize, $thumb_h_resize)) return FALSE;

    // STORE THE FINAL IMAGE - WILL OVERWRITE $thumb_image_url
    if (!imagejpeg($final, $thumb_image_url, $quality)) return FALSE;
    return TRUE;
}

// USE CASE
resize_and_crop('RAY_temp_600x374.jpg', 'RAY_temp_100x100.jpg', 100, 100);
resize_and_crop('RAY_temp_600x374.jpg', 'RAY_temp_200x100.jpg', 200, 100);
resize_and_crop('RAY_temp_600x374.jpg', 'RAY_temp_200x300.jpg', 200, 300);

Open in new window

0
 
R-ByterAuthor Commented:
Thanks for Your help Ray and Im awarding You the points. With the help of Your detailed solution I managed to find out the way to correct my code.
So I changed this line:

$thumb = imagecreatetruecolor($newwidth, $newheight);

to:

$thumb = imagecreatetruecolor($item[0], $item[1]);

just as You did before using imagecopy. Then I tried to use only one imagecopyresampled command and it worked so Im asking You to tell me is it a good practice or do you see any flaw in this (I have great confidence in You and Your solutions here at EE):

imagecopyresampled($thumb, $source, 0 - ($newwidth - $item[0]) / 2, 0 - ($newheight - $item[1]) / 2, 0, 0, $newwidth, $newheight, $width, $height);
0
 
Ray PaseurCommented:
Thanks for the points.  As to "is it a good practice" -- I have no idea.  

As a general rule I do not like compound statements.  They hide information from the standard debugging tools like "var_dump()."  So if you needed to know the value of "0 - ($newheight - $item[1]) / 2" but it was being computed as part of the function call, you're hosed.

Best of luck with the project, ~Ray
0
 
R-ByterAuthor Commented:
Thanks again Ray. Its always good to hear practical advices from You.
0
 
Ray PaseurCommented:
Glad to help.  Over and out until next time...
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now