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.
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 have 2 different scripts for handling images:
The first one is a watermark script for watermarking images on the fly:
$imgpath=$_REQUEST['filename'];
header('content-type: image/jpeg');
$watermarkfile="assets/img/logo_variations/logo_watermark_75.png";
$watermark = imagecreatefrompng($watermarkfile);
list($watermark_width,$watermark_height) = getimagesize($watermarkfile);
$image = imagecreatefromjpeg($imgpath);
$size = getimagesize($imgpath);
$dest_x = ($size[0] - $watermark_width)/2;
$dest_y = ($size[1] - $watermark_height)/2;
imagecopy($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);
imagejpeg($image);
imagedestroy($image);
imagedestroy($watermark);
So the image URL for a watermarked image is: http://example.com/watermark.php?filename=assets/img/temp/temp_share.jpg or since I'm using mod_rewrite to "pretty up" my URL: http://example.com/watermark/assets/img/temp/temp_share.jpg.
Works like a charm and my reason for doing so like this is because this is on a modeling website where I want to display the images without watermarks but I use a jquery script to change the image source of the image gets right clicked(assuming a user is trying to save the image).
The script only changes the source of any image with a class of img-protected.
I've written it to ignore any image with watermark in the URL so that it doesn't try to change the already watermarked image which would result in a url like: http://example.com/watermark/watermark/img.jpg which would result in a broken image. The other part is written to remove http://example.com from the original source so I don't end up with http://example.com/watermark/http://example.com/img.jpg.
$('.img-protected').on('mousedown', function (event) {
if (event.which == 3) {
if(this.src.indexOf("watermark") > -1) {
return false;
}
else {
src = this.src.replace('http://example.com/','');
this.src = 'http://example.com/watermark/' + src;
}
}
});
All of this works exceptionally well until I added another image handling script:
I'm using TimThumb.php which is an on the fly image resize script I use for creating gallery icons instead of uploading an icon and a full size image(this is how I wish to keep doing so as well).
The problem I am facing is this:
If I have an image that is being turned into a thumbnail using TimThumb.php which I renamed to thumb.php on my server the URL is http://example.com/thumb.php?src=gallery/goth/industrial_brick/5361ae7de9404.jpg&w=350&h=500a=c&s=1&f=11 which gives me an icon for 5361ae7de9404.jpg.
All of my icons have a class of img-protected which means on right click the above URL is going to be changed to the watermarked one.
This is where it fails.
The outputed URL when right clicked is http://example.com/watermark/http://www.example.com/thumb.php?src=gallery/goth/industrial_brick/5361ae7de9404.jpg&w=350&h=500a=c&s=1&f=11 which results in a broken image.
I manually tried making the URL into http://example.com/watermark/thumb.php?src=gallery/goth/industrial_brick/5361ae7de9404.jpg&w=350&h=500a=c&s=1&f=11 to see if that would change anything but it still results in a broken image.
What I need is to be able to also watermark the generated icons from thumb.php using watermark.php.
Is there a way to combine these two scripts or a workaround to make this work?
I'm at a complete loss here.
EDIT: I am fully aware that advanced users can still acquire the non watermarked image since it's already been downloaded to there device, but I don't expect a high volume of users to visit this particular website as this is simply a local models portfolio.
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've installed the GD Library on my Apache just now, and it seems that my script below doesn't work.
I'm trying to add a layer "play.png" to a youtube video thumbnail (http://img.youtube.com/vi/VIDEOID/default.jpg)
I've tried it with many different videoID's but the image doesn't load. There is a message that the graphic couldn't be opened because it contains errors.
I'm opening the file with postimage.php?v=7yV_JtFnIwo
http://img.youtube.com/vi/7yV_JtFnIwo/default.jpg opens correctly too...
Does anyone know where the issue could be?
Thanks in advance!
<?php
// The header line informs the server of what to send the output
// as. In this case, the server will see the output as a .png
// image and send it as such
header ("Content-type: image/png");
// Defining the background image. Optionally, a .jpg image could
// could be used using imagecreatefromjpeg, but I personally
// prefer working with png
$background = imagecreatefromjpeg("http://img.youtube.com/vi/".$_GET['v']."/default.jpg");
// Defining the overlay image to be added or combined.
$insert = imagecreatefrompng("play.png");
// Select the first pixel of the overlay image (at 0,0) and use
// it's color to define the transparent color
imagecolortransparent($insert,imagecolorat($insert,0,0));
// Get overlay image width and hight for later use
$insert_x = imagesx($insert);
$insert_y = imagesy($insert);
// Combine the images into a single output image. Some people
// prefer to use the imagecopy() function, but more often than
// not, it sometimes does not work. (could be a bug)
imagecopymerge($background,$insert,0,0,0,0,$insert_x,$insert_y,100);
// Output the results as a png image, to be sent to viewer's
// browser. The results can be displayed within an HTML document
// as an image tag or background image for the document, tables,
// or anywhere an image URL may be acceptable.
imagepng($background,"",100);
?>
Do not close (avoid whitespaces or newslines) your script with ?> and use NULL instead "".
imagepng($background, NULL);
Then, in imagepng the quality parameter is between 0 and 9, as in http://it.php.net/manual/en/function.imagepng.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.