Images Rotating - php

I have a very strange problem.
On my website there is a file field that will allow the users to upload their profile picture.
It gets uploaded using JQuery and it gets saved using PHP.
If I upload from a PC / MAC / iPhone then there is no problem whatsoever, however if I upload using an Android device the image gets rotated.
The rotation is not even consistent, it could be 90% 180% or 270%, this happens when taking a image or selecting from the Gallery.
Why would this happen? and is there a possible fix?

This solved the issue
From the PHPDocs
<?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

PHP - Read an image with URL

Here my problem, I do a query to MySQL (PDO) for give me the last 5 URLs of a table nammed avatar who contains the ID and the URL :
$response = $dbh->query("SELECT url FROM avatar ORDER BY id_URL DESC LIMIT 0,5 ");
And I did :
while ($donnees = $response->fetch())
{
$urlImage = $donnees['url']; //'url' contains the URL
$result = file_get_contents($urlImage);
header('Content-Type: image/png');
echo $result;
?>
But the header just return a small empty white square. However, the "$result = file_get_contents($urlImage);" takes properly the URL because when I do :
$urlImage = $donnees['url']; //'url' contains the URL
$result = file_get_contents($urlImage);
echo $result;
?>
It just shows the "encodage of the image" (a ton of special characters) but not displays the image.
I also try with "imagick" but it says to me that the class doesn't exist and I don't think that the imagecreatefrompng can be use with URL.
Thanks !
Can you try this and see if it works?
$image = file_get_contents($donnees['url']);
$finfo = new finfo(FILEINFO_MIME_TYPE);
header('content-type: ' . $finfo->buffer($image));
echo $image;
This is suppose to handle one Image. One php script can return one image. If you want to combine the images and render a big long image then probably you should look at http://image.intervention.io/
EDIT
What I understood after trying out the above code is that if you put file_get_contents before header then the raw characters are shown. However you put it after header then everything seems to be working
$image="http://www.hillspet.com/HillsPetUS/v1/portal/en/us/cat-care/images/HP_PCC_md_0130_cat53.jpg";
$filename = basename($image);
$file_extension = strtolower(substr(strrchr($filename,"."),1));
switch( $file_extension ) {
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpeg"; break;
default:
}
header('Content-type: ' . $ctype);
$image = file_get_contents($image);
echo $image;
Working fiddle
If you're trying to use a dynamic image source where your url is the image source, and it isn't working, then the problem might be that there's a space or extra character somewhere on the page, which will make the browser treat it like a document instead of an image in some cases.
Your problem is that the browser isn't understanding that it's supposed to be an image.
You could always do:
<img src="<?=$urlImage?>">

Send image from android - receives rotated picture on server

I am trying to write an android app that takes a picture and saves it to a server. The problem is that every picture I take is rotated with -90 degrees when saved on the server. Any idea how I can rotate the picture in php or why it ends up being rotated?
This is how my php file looks like:
<?php
$file_path = "photos/";
$img = $_REQUEST['base64'];
$name=$_REQUEST['ImageName'];
// Decode Image
$binary=base64_decode($img);
$success = file_put_contents($file_path.$name, $binary);
if($success === false) {
echo "Couldn't write file";
} else {
echo "Wrote $success bytes";
}
echo $name;
?>
It isn't a server side issue, every smartphone can apply a different orientation to the camera images.
When you receive the image you have to access to its metadata (exif data si the exact name) to verify its rotation and other properties. Then you should apply to the picture the transformations you need.
This should be a good startpoint to read exif data with PHP: http://php.net/manual/en/function.exif-read-data.php
Maybe it has something to do with image orientation.
Try this
$exif = exif_read_data($file_path.$name);
$ort = $exif['IFD0']['Orientation'];
switch($ort)
{
case 3: // 180 rotate left
$image->imagerotate($file_path.$name, 180, -1);
break;
case 6: // 90 rotate right
$image->imagerotate($file_path.$name, -90, -1);
break;
case 8: // 90 rotate left
$image->imagerotate($file_path.$name, 90, -1);
break;
}

Picture upload issue with php

I have some code that is supposed to allow the user to browse his machine for jpeg, gif, or png to upload.
My code works fine from my xampp localhost.
I have upload my code to Amazon Web Services where I have a Ubuntu 12.04 server that I installed a LAMP on. Once there the code does not work.
I have tracked down where I believe the code fails. It is at getimagesize($old_image_path) this returns a empty set.
$old_image_path = /var/www/ch23_ex1/images//leaf.gif when I select a pic from my desktop, not sure why this path shows but it worked with xampp.
Notice the echo statements that included for testing the output from these is:
allow_url_fopen = 1
/var/www/ch23_ex1/images//NChandler03.jpgbool(false) Image type = File must be a JPEG, GIF, or PNG image.
Here is the section of code where I believe the fail is:
function resize_image($old_image_path, $new_image_path,
$max_width, $max_height) {
echo "allow_url_fopen = " . ini_get("allow_url_fopen")."<br>";
// Get image type
echo $old_image_path;
//$image_info = file_get_contents($old_image_path);
$image_info = getimagesize($old_image_path);
$image_type = $image_info[2];
var_dump($image_info);
echo 'Image type = '.$image_type;
// Set up the function names
switch($image_type) {
case 2:
$image_from_file = 'imagecreatefromjpeg';
$image_to_file = 'imagejpeg';
break;
case 1:
$image_from_file = 'imagecreatefromgif';
$image_to_file = 'imagegif';
break;
case 3:
$image_from_file = 'imagecreatefrompng';
$image_to_file = 'imagepng';
break;
default:
echo $image_type;
echo 'File must be a JPEG, GIF, or PNG image.';
exit;
}
}
I found my answer posted on similar question. All I had to do was change the permissions on the images file by entering the following code into the server. This first command changes the directory to the file that holds my images file. The second command changes the permissions of the images file so that my code can write to it. I hope this helps someone else.
cd /var/www/ch23_ex1/
sudo chmod 775 images

Image display using php without affecting the html code

I have a question about the images displaying using a function getImage_w($image,$dst_w), which takes the image URL ($image) and the destination width for this image ($size). Then it re-draws the image changing its height according to the destination width.
That's the function (in libs/image.php file):
function getImage_w($image,$w){
/*** get The extension of the image****/
$ext= strrchr($image, ".");
/***check if the extesion is a jpeg***/
if (strtolower($ext)=='.jpg' || strtolower($ext)=='.jpeg'){
/***send the headers****/
header('Content-type: image/jpeg');
/**get the source image***/
$src_im_jpg=imagecreatefromjpeg($image);
/****get the source image size***/
$size=getimagesize($image);
$src_w=$size[0];
$src_h=$size[1];
/****calculate the distination height based on the destination width****/
$dst_w=$w;
$dst_h=round(($dst_w/$src_w)*$src_h);
$dst_im=imagecreatetruecolor($dst_w,$dst_h);
/**** create a jpeg image with the new dimensions***/
imagecopyresampled($dst_im,$src_im_jpg,0,0,0,0,$dst_w,$dst_h,$src_w,$src_h);
imagejpeg($dst_im);
}
In a file imagetest.php I have this code portion:
<?php
require 'libs/image.php';
echo '<h1>HELLO WORLD : some html</h1>
<img src="'.displayImg_w('http://www.sanctius.net/wp-content/uploads/2010/05/Avatar-20.jpg',200).'">
';
In the past, I used to write the URL with $_GET paramers defining the image. But now , I want to use the function directly in my code.
The problem is that the image is displaying correctly, but the Hello World HTML code is not translated by the browser (I know that the header are already sent by the first code) But I want to know how to display the image correctly without affecting the html code. and also without using get parameters that change the URL of the image to this undesired form :
libs/image.php?image=http://www.example.com/image&width=200
After my earlier, totally wrong answer, I hope to make up for it with this. Try this code:
<?php
function getImage_w($image,$w){
// Get the extension of the file
$file = explode('.',basename($image));
$ext = array_pop($file);
// These operations are the same regardless of file-type
$size = getimagesize($image);
$src_w = $size[0];
$src_h = $size[1];
$dst_w = $w;
$dst_h = round(($dst_w/$src_w)*$src_h);
$dst_im = imagecreatetruecolor($dst_w,$dst_h);
// These operations are file-type specific
switch (strtolower($ext)) {
case 'jpg': case 'jpeg':
$ctype = 'image/jpeg';;
$src_im = imagecreatefromjpeg($image);
$outfunc = 'imagejpeg';
break;
case 'png':
$ctype = 'image/png';;
$src_im = imagecreatefrompng($image);
$outfunc = 'imagepng';
break;
case 'gif':
$ctype = 'image/gif';;
$src_im = imagecreatefromgif($image);
$outfunc = 'imagegif';
break;
}
// Do the resample
imagecopyresampled($dst_im,$src_im,0,0,0,0,$dst_w,$dst_h,$src_w,$src_h);
// Get the image data into a base64_encoded string
ob_start();
$outfunc($dst_im);
$imgdata = base64_encode(ob_get_contents()); // Don't use ob_get_clean() in case we're ever running on some ancient PHP build
ob_end_clean();
// Return the data so it can be used inline in HTML
return "data:$ctype;base64,$imgdata";
}
echo '<h1>HELLO WORLD : some html</h1>
<img src="'.getImage_w('http://www.sanctius.net/wp-content/uploads/2010/05/Avatar-20.jpg',200).'" />
';
?>
This basically is not possible. The webbrowser requests the HTML page and expects HTML. Or it requests an image and expects an image. You cannot mix both in one request, just because only one Content-Type can be valid.
However, you can embed the image in HTML using data URI:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4/8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
Be aware that the base64 encoding is quite ineffective, so make sure you definitly compress your output, if the browser supports it, using for example gzip.
So for you it likely looks like the following:
echo '<img src="data:image/jpeg;base64,' . base64_encode(displayImg_w('http://www.sanctius.net/wp-content/uploads/2010/05/Avatar-20.jpg',200)) . '">';
And make sure displayimg_w() does not output a header anymore.
Furthermore, displayimg_w() needs to be adjusted at the end to return the image data as string rather than direct output:
ob_start();
imagejpeg($dst_im);
return ob_get_flush();

Images rotate automatically

I have a iPhone app that uploads pictures to my server. One major issue I am having is a rotating one.
For some reason if I upload a picture from my iPhone, some pictures will automatically rotate. The one's that do get rotated are the ones in portrait mode. I have no code in my script that rotates the images.
How does a server exactly process tall images? Should I modify my php file to check to rotate it ahead after it automatically rotates? Should I code something in my iPhone app that will check this?
Any help is appreciated!
PS: If you need code, feel free to ask!
Some pictures(jpg) have exif data that tells the position the camera was when the picture was shot.
Take a look at http://www.php.net/manual/en/function.exif-read-data.php#76964
You may rotate the pictures server-side like this
Or a better way is to use this library
https://github.com/Intervention/image
And simply use like this-
$img = Image::make('foo.jpg')->orientate();
More can be found here.
When you take a picture your phone saves any rotation metadata in EXIF headers. When you upload the image to your server, that metadata is still sitting there but it's your job to apply it to the image to rotate it (if you want). In PHP you can use a function called exif_read_data:
function correctImageOrientation($filename)
{
$exif = exif_read_data($filename);
if ($exif && isset($exif['Orientation'])) {
$orientation = $exif['Orientation'];
if ($orientation != 1) {
$img = imagecreatefromjpeg($filename);
$deg = 0;
switch ($orientation) {
case 3:
$deg = 180;
break;
case 6:
$deg = 270;
break;
case 8:
$deg = 90;
break;
}
if ($deg) {
$img = imagerotate($img, $deg, 0);
}
imagejpeg($img, $filename, 95);
}
}
}
To use it simply call the function after you save the file. For more info and an additional PHP solution see the original source.

Categories