I am trying to make a function in PHP that will allow me to enter basically any URL and then runs some functions on it just as if a user was uploading on my server. SO I will resize and make some thumbnails but I need help just getting the image in a state that I can run my other codes on it. Another user on this site helped me get started with ImageCreateFromString() and file_get_contents()
Please note this code is missing a lot of stuff I am aware of, I am just trying to get the basic function working and then I will add in all the security measures
I tried this code below using a URL like this with the photo URL added to my script url:
http://example.com/friendproject2/testing/photos/fromurl/?url=http://a0.twimg.com/a/1262802780/images/twitter_logo_header.png
But it shows nothing and not even an error
function getphotoURL($url){
if(isset($url) && $url != 'bad') {
$image = ImageCreateFromString(file_get_contents($url));
if (is_resource($image) === true){
echo 'The URL of the image we fetch is :' .$url. '<BR><BR>';
//show image
header('Content-Type: image/jpeg');
imagejpeg($image, null, 100);
imagedestroy($image);
imagedestroy($image);
// image is valid, do your magic here
}else{
// not a valid image, show error
echo 'error getting URL photo from ' .$url;
}
}else{
//url was empty
echo 'The URL was not passed into our function';
}
}
?>
###### UPDATE #####
It seems it was a simple error on my part, something simple as checking for a POST request instead of a GET request, here is my new code below.
I have a couple of issues,
1) I am using imagejpeg($image, null, 100); and I am wondering, should I be using something else? Does it require the source image to be a jpg or will it work with any image? I need to allow the main types (jpg, jpeg, gif, png)
2) same as above question but for when showing the image on screen I have header set to this: header('Content-Type: image/jpeg'); should it not be jpg for other type of images?
3) Is there a way that I can make sure that the source URL passed in is an actual image and do whatever I want if it is not a image, like show my own error or do my own code once it detect that the URL is not a valid image url
<?PHP
// run our function
if(isset($_GET['url']) && $_GET['url'] != "") {
getphotoURL($_GET['url'],'no');
}
function getphotoURL($url, $saveimage = 'yes'){
if(isset($url) && $url != '') {
$image = imagecreatefromstring(file_get_contents($url));
if (is_resource($image) === true){
if($saveimage === 'yes'){
// resize image and make the thumbs code would go here if we are saving image:
// resize source image if it is wider then 800 pixels
// make 1 thumbnail that is 150 pixels wide
}else{
// We are not saving the image show it in the user's browser
header('Content-Type: image/png');
imagejpeg($image, null, 100);
imagedestroy($image);
}
}else{
// not a valid resource, show error
echo 'error getting URL photo from ' .$url;
}
}else{
// url of image was empty
echo 'The URL was not passed into our function';
}
}
?>
After calling imagecreatefromstring() for a PNG or GIF (For transparency)
Do the following manipulations on the image:
imagealphablending($image, true); // setting alpha blending on
imagesavealpha($image, true);
Will turn the flat black background to the alpha channel.
In response to your new questions:
1) I am using imagejpeg($image, null,
100); and I am wondering, should I be
using something else? DOes it require
the source image to be a jpg or will
it work wiht any image? I need to
allow the main types (jpg, jpeg, gif,
png)
Well, php.net says, "imagejpeg() creates a JPEG file from the given image". But the important part is this, "An image resource, returned by one of the image creation functions, such as imagecreatetruecolor().". And your using "imagecreatefromstring() returns an image identifier representing the image obtained from the given data . These types will be automatically detected if your build of PHP supports them: JPEG, PNG, GIF, WBMP, and GD2."
So, that should be ok.
2) same as above question but for when
showing the image on screen I have
header set to this:
header('Content-Type: image/jpeg');
should it not be jpg for other type of
images?
The header should be of type jpg - If that's the file type, then you're correct.
3) Is there a way that I can make sure
that the source URL passed in is an
actual image and do whatever I want if
it is not a image, like show my own
error or do my own code once it detect
that the URL is not a valid image url
Yeah - Instead of doing:
$image = ImageCreateFromString(file_get_contents($url));
You could do:
$image = imagecreatefromjpeg($url);
if (!$image) echo "error";
imagecreatefromjpeg() returns an image
identifier representing the image
obtained from the given filename.
But really, what you have is fine.
Does it display the error message
echo 'The URL was not passed into our function';
Or nothing at all?
If the error messaging is being displayed, possible the check === is failing:
An image resource will be returned on
success. FALSE is returned if the
image type is unsupported, the data is
not in a recognised format, or the
image is corrupt and cannot be loaded.
Also, do you have error logging maxed out on your development server? That way you can see any possible warnings being thrown?
Related
I'm displaying an image where the URL is kept in the database, now i want to display it completely black if a condition isn't met
The URL
$url = '/images/'.$row['sprite'].'.png';
its then displayed in a normal image tag
What i want is if $row['normal'] == 0 then black the image, making it a silhouette, otherwise display the normal image
After some searching I've found about imagefilter but am not sure how to apply it, as the examples i've found don't show how to apply it when there is other content on the page
Or would it be better to make the silhouettes in photoshop, given that there is over 800 of them, though only a maximum of two on the page
Firstly you need to load GD Image Library to your server.
Define your image path and create an image object by using imagecreatefrompng if your image types are different choose correct one.
$image_path = $_SERVER['DOCUMENT_ROOT']."/assets/img/horse1.png";
$image_obj = imagecreatefrompng($image_path);
Now, we need to apply a filter, if your conditions provided. Using the imagefilter function to apply any filter to your image. In this example IMG_FILTER_GRAYSCALE is fair enough or you can change it by using the manual of function.
if($row['normal'] == 0) {
$op_result = imagefilter($image_obj,IMG_FILTER_GRAYSCALE);
}
Finally, we need save the image to server using by imagepng function.
imagepng($image_obj,$_SERVER['DOCUMENT_ROOT']."/assets/img/horse1_black.png");
Check the full code below beacuse I strongly suggest that, you shouldn't create black image for every single user. If your image is already exist in your server just show it without any creation.
$image_path = $_SERVER['DOCUMENT_ROOT']."/assets/img/horse.png";
$black_image_path = $_SERVER['DOCUMENT_ROOT']."/assets/img/horse_black.png";
if($row['normal'] == 0) {
if(file_exists($black_image_path)){
return $black_image_path; //if your black image is already exist just return and use it.
}
else {
$image_obj = imagecreatefrompng($image_path); //create a image object from a path
$op_result = imagefilter($image_obj,IMG_FILTER_GRAYSCALE); //applying grayscale filter to your image object.
if($op_result) {
imagepng($image_obj,$black_image_path); //save the image to defined path.
return $black_image_path;
}
else {
return "Error Occured.";
}
}
}
I am using phalcon php framework. I have a blog in my application where a user can submit an image attached to his blog post, and it is displayed when viewing the post. I want to display this image on the index page of the blog where each post is listed, however, i want it to be a thumbnail to reduce its size. I was able to use imagick to save a thumbnail at a directory and load the thumbnail from there, however, i need to avoid saving the thumbnail and generate the thumbnails every time just to display them.
Here is the code I used to create the image with imagick
public function thumbnail($img)
{
$maxsize = 100;
$image = new Imagick($img);
// Resizes to whichever is larger, width or height
if($image->getImageHeight() <= $image->getImageWidth())
{
$image->resizeImage($maxsize,0,Imagick::FILTER_LANCZOS,1);
}
else
{
$image->resizeImage(0,$maxsize,Imagick::FILTER_LANCZOS,1);
}
// Set to use jpeg compression
$image->setImageCompression(Imagick::COMPRESSION_JPEG);
// Set compression level (1 lowest quality, 100 highest quality)
$image->setImageCompressionQuality(75);
// Strip out unneeded meta data
$image->stripImage();
// Writes resultant image to output directory
$image->writeImage($uploaddir.'/thumbs/'. basename($_FILES['photo']['name']));
// Destroys Imagick object, freeing allocated resources in the process
$image->destroy();
}
I tried just to remove the last two lines where the image is saved and then the imagick object is destroyed, but couldn't go on to display the image in the index view.
Step 1 - Use the buffer.
Step 2 - Unlink the already saved image after you get its base64 code.
For example consider the following code snippet:
$im = new Imagick();
$im->setResolution(300,300);
$im->readimage('path_to_the_file.pdf');
$im->setImageFormat('jpeg');
$im->writeImages('file_name_to_save.jpg', false);
$im->clear();
$im->destroy();
$dest = imagecreatefromjpeg ('file_name_to_save.jpg');
//Step 1
ob_start();
imagejpeg($dest);
$image_data = ob_get_clean();
imagedestroy($dest);
$img_source = base64_encode($image_data);
//Step 2
unlink('file_name_to_save.jpg');
Now in the $img_source variable you have the base64 of the image that you can use it like this:
'<img src="data:image/jpg;base64,'.$img_source.'" style="max-width: 100%; max-height:100%;" />';
I'm using something similar to this:
public function thumbAction() {
// Generate thumb from image & save it on disk
$image = $this->thumbnail(); // well can be anything that return Imagick
$this->response->setHeader('Content-Type', 'image/jpg');
echo $image;
}
Anyway in above example you don't need to save the image but only echo created thumb to the user.
Also I'm storing an image on some path like thumbs/a/image.jpg. I've configured nginx to check for existing file and if file does not exists it calls Phalcon script.
In Phalcon app I have a route that points to any /thumbs* path to above action. On first call the image is saved on the path thumbs/a/ so on the next call Nginx server returns that image instead of calling PHP.
been trying to detect the image orientation of uploaded images from iPhones and then adjust their orientation from that.
I am trying to fix the issue where images taken in potrait, are uploaded with a -90 degree rotate. I tried numerous switch statements which were not working, so decided to return the exif data in my JSON return.
The issue i see is that their is no orientation in the exif data.
I am doing so:
$imagefile = $fileToUpload["tmp_name"];
$destinationImage = imagecreatefromstring(file_get_contents($imagefile));
$exif = exif_read_data($imagefile);
$moveUploadedFile = imagejpeg($destinationImage, $this->uploadDir . "/" . $newFileName, 100);
imagedestroy($destinationImage);
if ($moveUploadedFile) {
$return['ort'] = $exif;
echo json_encode($return);
}
What i am seeing in my return (using firebug) is:
FileName:"phpUQZFHh"
FileDateTime:1410465904
FileSize:473421
FileType:2
MimeType:"image/jpeg"
SectionsFound:"COMMENT"
Computed: OBJECT:
Height:700
Width:933
IsColor:1
Comment: ARRAY:
0:"CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 100"
I want to be able use the exif data like so:
if (!empty($exif['Orientation'])){
//get the orientation
$ort = $exif['Orientation'];
//determine what oreientation the image was taken at
switch($ort){
case 2: // horizontal flip
break;
case 3: // 180 rotate left
$destinationImage = imagerotate($destinationImage, 180, -1);
break;
}
}
Any help?
EDIT: After downloaded an image that had been uploaded and checking its properties it appears that all exif data was removed in the upload process.
This still baffles me as to why it is rotated before / during upload / how to fix this.
I guess the "Orientation" value presents in the returned data of exif_read_data function in case when you upload the picture from your iOS device only. It won't work in desktop browser. I might be wrong.
I ran into the same problem. Turns out some images really did not have any exif data on Orientation at all -- usually ones with the "correct" orientation do not have it. I tried one landscape image taken with an iPhone and there was.
In your case, the photos may have had no exif data in the first place. I had some photos like that as well (rotated -90 degrees but no Orientation info). I could be wrong but without exif data, there's no programmatic way to know if an image is incorrectly oriented.
For incorrectly oriented photos without Orientation info, I suggest you just make sure the user sees (gets a preview) of what about to be uploaded. IME, most users are more than willing to get out of their way to fire up paint/photoshop/etc. just to ensure they have good looking photos.
You can get Orientation value before move the file to the server directory (Worked with iPhone as well)
$image = $_FILES["image"]["tmp_name"];
$orientation = '';
if (function_exists('exif_read_data'))
{
$exif = exif_read_data(image);
if($exif && isset($exif['Orientation']))
$orientation = $exif['Orientation'];
}
Using the safari mobile browser with IOS6, the file upload function gives users the option to snap a photo. Unfortunately, upon snapping the photo, while the photo thumb shows up properly in the browser, when you upload to a server, the file is rotated 90 degrees. This appears to be due to the exif data that the iphone sets. I have code that fixes the orientation by rotating the image when serving. However, I suspect it would be better to save the rotated, properly oriented, image so I no longer have to worry about orientation. Many of my other photos do not even have exif data and i don't want to mess with it if I can avoid it.
Can anyone suggest code to save the image so it is properly oriented?
Here is the code that rotates the image. The following code will display the properly oriented image, however, what I want to do is save it so I can then serve it whenever I want without worrying about orientation.
Also I would like to replace impagejpeg call in code below so that any code works for gifs as well as jpgs.
Thanks for suggestions/code!
PHP
//Here is sample image after uploaded to server and moved to a directory
$target = "pics/779_pic.jpg";
$source = imagecreatefromstring(file_get_contents($target));
$exif = exif_read_data($target);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']) {
case 8:
$image = imagerotate($source,90,0);
//echo 'It is 8';
break;
case 3:
$image = imagerotate($source,180,0);
//echo 'It is 3';
break;
case 6:
$image = imagerotate($source,-90,0);
//echo 'It is 6';
break;
}
}
// $image now contains a resource with the image oriented correctly
//This is where I want to save resource properly oriented instead of display.
header('Content-type: image/jpg');
imagejpeg($image);
?>
Only JPEG or TIFF files can carry EXIF metadata, so there's no need to worry about handling GIFs (or PNGs, for that matter) with your code.
From page 9 of what I believe is the official specification:
Compressed files are recorded as JPEG (ISO/IEC 10918-1) with application marker segments (APP1 and APP2) inserted. Uncompressed files are recorded in TIFF Rev. 6.0 format.
http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf
To save your image just use the same function imagejpeg and the next parameter to save the image, something like:
imagejpeg($image, $target, 100);
In this case you don't need the specify the header, because you are not showing nothing.
Reference:
http://sg3.php.net/manual/en/function.imagejpeg.php
I am trying to build a class that does many photo operations, one method will upload images from a user but I am also needing to build a method to grab a photo from a URL and run other methods on it just like if it were being uploaded with a POST form from user.
Below is my start of the function for getting image from URL, it works but needs work still. Below the code you can see a image that is the result of this function being ran. Also is the original image to see what it should look like. You can see that this function makes the image have a black background on this transparent image. How can I make it look better like it should look?
$url = 'http://a0.twimg.com/a/1262802780/images/twitter_logo_header.png';
//run our function
savePhotofromURL($url, 'no');
// photo function should grab an photo from a URL
function savePhotofromURL($photo_url, $saveimage = 'yes'){
if(isset($photo_url) && $photo_url != '') {
//get info about photo
$photo_info = getimagesize($photo_url);
$source_width = $photo_info['0'];
$source_height = $photo_info['1'];
$source_type = $photo_info['mime'];
//grab the Photo from URL
$photo = imagecreatefromstring(file_get_contents($photo_url));
if (is_resource($photo) === true){
if($saveimage === 'yes'){
// TO DO: resize image and make the thumbs code would go here if we are saving image:
// TO DO: resize source image if it is wider then 800 pixels
// TO DO: make 1 thumbnail that is 150 pixels wide
}else{
// We are not saving the image show it in the user's browser
// TO DO: we will add in correct photo type soon
header('Content-Type: image/gif');
imagejpeg($photo, null, 100);
imagedestroy($photo);
}
}else{
// not a valid resource, show error
echo 'error getting URL photo from ' .$photo_url;
}
}else{
// url of image was empty
echo 'The URL was not passed into our function';
}
}
The result looks like this
alt text http://img2.pict.com/52/05/1f/2429493/0/screenshot2b181.png
Instead of like this
The following two calls will tell php to use the alpha blending present in the png image:
ImageAlphaBlending($photo, false);
ImageSaveAlpha($photo, true);
Edit:
I see you're outputting the image as a JPEG also. JPEGs don't support transparency, so no matter what you do you will end up with an incorrect background color. Also see this related question: PHP/GD ImageSaveAlpha and ImageAlphaBlending
You need to add better support for image types and by extension their transparency.
Since the image is transparent we can know that its either a GIF or a PNG yet your sending the GIF header while using imagejpeg() - jpegs dont support any kind of transparency. But if its a png you may also have to account for if its alpha trans or index transparency.