Width and Height values are automatically swapped after uploading to server. [PHP] - php

I used this function getimagesize($file_tmp_name) to get width and height of the image I uploaded.
The function returned a 2D array: $width = arr[0] and $height = arr[1];
On my PC, the image demension is: 3024 x 4032 (w x h)
But on the server side, the image width and height values are swapped. 4032 x 3024 (w x h)
var_dump($width); // C:\wamp64\www\upload_script\Image.php:89:int 4032
var_dump($height); // C:\wamp64\www\upload_script\Image.php:90:int 3024
I'm not sure what caused this and how can I make it consistent. I appreciate any help.

You can check first comment on exif_read_data function in php manual.
Code copied from there:
<?php
$image = imagecreatefromstring(file_get_contents($_FILES['image_upload']['tmp_name']));
$exif = exif_read_data($_FILES['image_upload']['tmp_name']);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']) {
case 8:
$image = imagerotate($image,90,0);
break;
case 3:
$image = imagerotate($image,180,0);
break;
case 6:
$image = imagerotate($image,-90,0);
break;
}
}
// $image now contains a resource with the image oriented correctly
?>

Related

Imagemagick does not set image to exact sizes

I have an image that i want to set to 1024 x 768 and this is the code i am using
<?php
function autoRotateImage($image) {
$orientation = $image->getImageOrientation();
switch($orientation) {
case imagick::ORIENTATION_BOTTOMRIGHT:
$image->rotateimage("#000", 180); // rotate 180 degrees
break;
case imagick::ORIENTATION_RIGHTTOP:
$image->rotateimage("#000", 90); // rotate 90 degrees CW
break;
case imagick::ORIENTATION_LEFTBOTTOM:
$image->rotateimage("#000", -90); // rotate 90 degrees CCW
break;
}
// Now that it's auto-rotated, make sure the EXIF data is correct in case the EXIF gets saved with the image!
$image->setImageOrientation(imagick::ORIENTATION_TOPLEFT);
}
$image = 'C:\xampp\htdocs\uncompressed_images\20221016_120159.jpg';
// Create new Imagick Object
$imagick = new Imagick($image);
// Set the Compression to COMPRESSION_JPEG
$imagick->setImageCompression(imagick::COMPRESSION_JPEG);
// Set the Compression quality
// This is where that compression method imagick::COMPRESSION_JPEG is
// used in the program.
$imagick->setImageCompressionQuality(26);
$imagick->thumbnailImage(1024,768);
autoRotateImage($imagick);
// Show the output
$imagick->setformat('jpg');
$imagick->writeImage($image);
header("Content-Type: image/jpg");
echo $imagick->getImageBlob();
?>
However the output image is always 768 x 1024 How can i have the resulting to be 1024 x 768?
How can i also write image to a specific directory in this line $imagick->writeImage($image); i.e output directory
You should use autoRotateImage to fix any orientation issue first (so now the image is in right orientation) , and then apply thumbnailImage for resizing
So change
$imagick->thumbnailImage(1024,768);
autoRotateImage($imagick);
to
autoRotateImage($imagick);
$imagick->thumbnailImage(1024,768);

How to get the orientation of an image in php

I am doing a project in core php. When i upload images which taken from mobile phone , it will display as inverted images. i am using exif_read_data function to get the orientation of image.and according to its value rotate the image. But i didn't get the orientation of all images.Is there any method to get the orientation of image?
This is the code
$exif_data = #exif_read_data($tmp_name);
if(!empty($exif_data['Orientation'])) {
switch($exif_data['Orientation']) {
case 8:
$image_p = imagerotate($image_p,90,0);
break;
case 3:
$image_p = imagerotate($image_p,180,0);
break;
case 6:
$image_p = imagerotate($image_p,-90,0);
break;
}
}
Well, you can check for the width and height of the image:
list($width, $height) = getimagesize('your-image.jpg'); // or other image ext
if ( $width > $height ) {
// Landscape image
}
elseif ( $width < $height ) {
// Portrait
}
else {
// Square
}
PS:
EXIF headers tend to be present in JPEG/TIFF images .. See here.
Resource for getimagesize() here.

Image is rotated correctly on mobile device, not on desktop

I'm having a weird issue with my uploaded images. They're rotated correctly when I view them on iPhones and iPads, but whenever I try to view them on desktop, they're displayed with their wrong orientation.
I can't find the error, and after spending hours messing with the EXIF data I'm close to giving up.
After fixing the orientation, I'm also resizing the images, but that shouldn't interfere with the other code. In case it does, I'm including it.
I don't have enough reputation to upload images, but here's a link to them:
http://i.imgur.com/ARwSUuV.png
http://i.imgur.com/00yj7OJ.png
Here's the code I'm using to upload:
$path_parts = pathinfo($_FILES["file"]["name"]);
$filepath = $_FILES['file']['tmp_name'];
$image = imagecreatefromstring(file_get_contents($filepath));
// Rotate image correctly!
$exif = exif_read_data($image);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']){
case 1: // nothing
break;
case 2: // horizontal flip
$image = imageflip($image, IMG_FLIP_HORIZONTAL);
break;
case 3: // 180 rotate left
$image = imagerotate($image,180,0);
break;
case 4: // vertical flip
$image = imageflip($image, IMG_FLIP_VERTICAL);
break;
case 5: // vertical flip + 90 rotate right
$image = imageflip($image, IMG_FLIP_VERTICAL);
$image = imagerotate($image,-90,0);
break;
case 6: // 90 rotate right
$image = imagerotate($image,-90,0);
break;
case 7: // horizontal flip + 90 rotate right
$image = imageflip($image, IMG_FLIP_HORIZONTAL);
$image = imagerotate($image,-90,0);
break;
case 8: // 90 rotate left
$image = imagerotate($image,90,0);
break;
}
}
switch ($path_parts['extension']) {
case 'gif' :
$im = imagecreatefromgif($image);
break;
case 'jpg' :
$im = imagecreatefromjpeg($image);
break;
case 'png' :
$im = imagecreatefrompng($image);
break;
case 'bmp' :
$im = imagecreatefrombmp($image);
break;
}
if($im){
imagejpeg($im, $_FILES['file']['tmp_name'], 40);
}
$image_path = 'd_'.time() . "." . $path_parts['extension'];
$move_result = move_uploaded_file($_FILES['file']['tmp_name'], '../img/results/' . $image_path);
If you have any idea why it's only rotating correctly on some platforms, I'd be very grateful!
EDIT: Should probably clarify that images will most often be uploaded from smartphones or tablets.
There are some errors that stop the code working. Try turning on error reporting to help you debug problems like this.
exif_read_data() works on a file, not a GD resource, so pass $filepath instead of $image.
imageflip() manipulates the resource directly and returns a bool so assigning the return value to $image destroys the resource.
The second switch() statement isn't needed at all. The imagecreatefrom___() functions create a resource from a file, but you're passing them an already created resource - all you want to do is output it.
Otherwise the orientation correction seems accurate and should work for you (it does on the various test photos I took with my phone).
Here's the corrected code:
$path_parts = pathinfo($_FILES["file"]["name"]);
$filepath = $_FILES['file']['tmp_name'];
$image = imagecreatefromstring(file_get_contents($filepath));
// Rotate image correctly!
$exif = exif_read_data($filepath);
if (!empty($exif['Orientation'])) {
switch ($exif['Orientation']) {
case 1: // nothing
break;
case 2: // horizontal flip
imageflip($image, IMG_FLIP_HORIZONTAL);
break;
case 3: // 180 rotate left
$image = imagerotate($image, 180, 0);
break;
case 4: // vertical flip
imageflip($image, IMG_FLIP_VERTICAL);
break;
case 5: // vertical flip + 90 rotate right
imageflip($image, IMG_FLIP_VERTICAL);
$image = imagerotate($image, -90, 0);
break;
case 6: // 90 rotate right
$image = imagerotate($image, -90, 0);
break;
case 7: // horizontal flip + 90 rotate right
imageflip($image, IMG_FLIP_HORIZONTAL);
$image = imagerotate($image, -90, 0);
break;
case 8: // 90 rotate left
$image = imagerotate($image, 90, 0);
break;
}
}
imagejpeg($image, $_FILES['file']['tmp_name'], 40);
$image_path = 'd_'.time() . "." . $path_parts['extension'];
$move_result = move_uploaded_file($_FILES['file']['tmp_name'], '../img/results/' . $image_path);

Cannot get exif imagetype data on specific jpeg image

I have a .jpg image (cjonline.com/sites/default/files/13183951.jpg) from a specific url that I cannot get the image size for because it will not process the exif data or getimagesize functions. I am able to get data for all other .jpg images just fine and I can't seem to understand why this one keeps failing. It loads fine in a browser.
$image = 'http://cjonline.com/sites/default/files/13183951.jpg';
try {
if ($image !== '') {
// Gets image width and length
switch (#exif_imagetype($image))
{
case 1: // gif -> jpg
$img = imagecreatefromgif($image);
break;
case 2: // jpeg -> jpg
$img = imagecreatefromjpeg($image);
break;
case 3: // png -> jpg
$img = imagecreatefrompng($image);
break;
default:
$img = '';
return array(0,0);
}
$imgWidth = imagesx($img);
$imgHeight = imagesy($img);
}
}
catch(Exception $e) { $img = ''; }
return array($imgWidth, $imgHeight);
You can get size with this:
list($width, $height) = getimagesize($image_file);

PHP Image cropping to square

I was using the following PHP script to create square thumbnails which I got here http://www.abeautifulsite.net/blog/2009/08/cropping-an-image-to-make-square-thumbnails-in-php/
I was able to integrate this into my image upload script, which uploads full sized image and after that takes the uploaded image and creates a thumbnail from that.
The problem is the author of the script said, it will crop landscape and portrait images without problem. It crops landscape images perfectly, but as it faces portrait image, the output thumbnail will not be cropped, but it appears scaled down to fit the given square thumbnail height and the emtpy space on the sides will be filled with black color.
I know there is a way to fix this, but as I am relatively new to PHP I am not able to solve it.
Can someome with real experience in PHP fix this?
Thank you in advance!
The script is here:
$
function square_crop($src_image, $dest_image, $thumb_size = 64, $jpg_quality = 90) {
// Get dimensions of existing image
$image = getimagesize($src_image);
// Check for valid dimensions
if( $image[0] <= 0 || $image[1] <= 0 ) return false;
// Determine format from MIME-Type
$image['format'] = strtolower(preg_replace('/^.*?\//', '', $image['mime']));
// Import image
switch( $image['format'] ) {
case 'jpg':
case 'jpeg':
$image_data = imagecreatefromjpeg($src_image);
break;
case 'png':
$image_data = imagecreatefrompng($src_image);
break;
case 'gif':
$image_data = imagecreatefromgif($src_image);
break;
default:
// Unsupported format
return false;
break;
}
// Verify import
if( $image_data == false ) return false;
// Calculate measurements
if( $image[0] & $image[1] ) {
// For landscape images
$x_offset = ($image[0] - $image[1]) / 2;
$y_offset = 0;
$square_size = $image[0] - ($x_offset * 2);
} else {
// For portrait and square images
$x_offset = 0;
$y_offset = ($image[1] - $image[0]) / 2;
$square_size = $image[1] - ($y_offset * 2);
}
// Resize and crop
$canvas = imagecreatetruecolor($thumb_size, $thumb_size);
if( imagecopyresampled(
$canvas,
$image_data,
0,
0,
$x_offset,
$y_offset,
$thumb_size,
$thumb_size,
$square_size,
$square_size
)) {
// Create thumbnail
switch( strtolower(preg_replace('/^.*\./', '', $dest_image)) ) {
case 'jpg':
case 'jpeg':
return imagejpeg($canvas, $dest_image, $jpg_quality);
break;
case 'png':
return imagepng($canvas, $dest_image);
break;
case 'gif':
return imagegif($canvas, $dest_image);
break;
default:
// Unsupported format
return false;
break;
}
} else {
return false;
}
}
?>
And I call it like this - square_crop('source_image', 'destination_image', 65);
You can see the result here http://imageshack.us/photo/my-images/717/imgfl.png/
It happens only with portrait images, landscape images are cropped in a way that it fills the whole square.
For cropping only, replace the imagecopyresampled() function with imagecopy().
The resampled performs an appropriate stretching or shrinking of the image if the source and destination coordinates and width and heights differ. imagecopy() doesn't.
you should add an image ration inside the if() statement, so it will understand if it's portrait or landscape.
change the line below
// Calculate measurements
if( $image[0] > $image[1] ) {

Categories