PHP GD - creating favicon.ico for InternetExplorer - php

I have a very simple PHP script which creates "favicon.ico" form jpg/gif/png uploaded file.
Here is a part of function:
$file = 'cache/'.$e .'/'. basename($_FILES['uploadfile']['name']);
if (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $file)) {
$im = imagecreatefromjpeg($file);
list($width, $height) = getimagesize($file);
$image_p = imagecreatetruecolor("16", "16");
imagecopyresampled($image_p, $im, 0, 0, 0, 0, "16", "16", $width, $height);
$num = rand (1,99999);
$output = $num."-favicon.ico";
imagepng($image_p,'dl/'.$output);
imagedestroy ($im);
unlink ($file);
echo 'success';
}
And script works fine! In Chrome, Opera and Firefox generated favicon displays good, as it should do.
But in Interent Explorer 8 - it simply doesn't show up.
Thank you for any help!

You can't just save it as a PNG with the ico extension... I'm guessing Chrome/Opera/Firefox can't read the file, so they decide to open up the file and find out what the actual format is rather than depending on the file extension, while IE doesn't.
However, you will need to find a different solution to save it as an ICO as GD can't do that on its own, you can either try ImageMagick or after a quick Google phpThumb seems to be able to do it (not tried).

Related

Attempting to merge a png over a jpg using PHP

I am trying to merge two images using PHP. One is a jpg that I have pulled in the form of a Facebook URL, the other is a "watermark" logo that is a png that I hope to apply in the bottom right hand corner of the Facebook image before posting the image back to Facebook.
I'm having trouble merging the two images. The function below is passed the url of the Facebook image (which is a jpg) $imagedata = the Facebook image URL. The function is currently returning: Resource id#1. I am hoping to save the merged image to the /uploads/ folder as the same previously randomly generated filename and return it's location from the function.
I have previously referenced this page:
Merge a png ontop of a jpg and retain transparency with php
function createImage($imagedata) {
$upload_dir = ($_SERVER['DOCUMENT_ROOT'] .'/uploads/');
$filename =generateFilename().'.jpg'; //generateFilename() does nothing more than create a random string to use as a unique filename
$filelocation=$upload_dir . $filename;
file_put_contents($filelocation,file_get_contents($imagedata));
$localimage = $filename;
$dest = imagecreatefromjpeg('/uploads/' . $localimage);
$src = imagecreatefrompng('images/overlay.png');
imagecopyresampled($dest, $src, $src2x, $src2y, 0, 0, $src2w, $src2h, $src2w, $src2h);
//header('Content-Type: image/png');
imagejpeg($dest, 'dickshlitz.jpg', 100);
imagedestroy($dest);
imagedestroy($src); }
Any and all help is deeply appreciated. Please ask questions if I have not been clear enough.
Okay, I got this working. My first issue was that I was confused by the output of imagecopyresampled() because I was trying to print it, which isn't what it's designed to do. At the time of posting the initial question I hadn't noticed the .jpg file was being output to my server, so really the code was already doing its job.
However, once I noticed the output and inspected it I noticed it wasn't functioning as expected. This was the fault of my not understanding imagecopyresampled() and passing it variables that hadn't been declared. After much tinkering the working code is below.
$dest = imagecreatefromjpeg('background.jpg');
$src = imagecreatefrompng('watermark.png');
imagesavealpha($src, true);
imagealphablending($src, true);
imagesavealpha($dest, true);
imagealphablending($dest, true);
list($newwidth, $newheight, $type, $attr) = getimagesize('overlay.png');
imagecopyresampled($dest, $src, 200 , 100, 0, 0, $newwidth , $newheight, $newwidth , $newheight);
imagepng($dest, $localimage);
imagedestroy($dest);
imagedestroy($src);
If anyone can make commnent to improve this code I would appreciate it.

Watermarking an image with php

My website (coded in html and php in entirety) includes a feature which allows certain users to upload pictures. The picture is resized and watermarked using this code:
function watermarkpic($filename) {
ini_set('max_input_time', 300);
require 'config.php';
$watermark = imagecreatefrompng('watermarknew.png');
$watermarkwidth = imagesx($watermark);
$watermarkheight = imagesy($watermark);
if(preg_match('/[.](jpg)$/', $filename)) {
$originalimage = imagecreatefromjpeg($path_to_image_directory . $filename);
} else if (preg_match('/[.](gif)$/', $filename)) {
$originalimage = imagecreatefromgif($path_to_image_directory . $filename);
} else if (preg_match('/[.](png)$/', $filename)) {
$originalimage = imagecreatefrompng($path_to_image_directory . $filename);
}
$originalwidth = imagesx($originalimage);
$originalheight = imagesy($originalimage);
$maxsize = 800;
$imgratio = $originalwidth / $originalheight;
if($imgratio > 1) {
$finalwidth = $maxsize;
$finalheight = $maxsize / $imgratio;
}
else {
$finalheight = $maxsize;
$finalwidth = $maxsize * $imgratio;
}
$finalimage = imagecreatetruecolor($finalwidth,$finalheight);
imagecopyresampled($finalimage, $originalimage, 0,0,0,0,$finalwidth,$finalheight,$originalwidth,$originalheight);
imagecopymerge($finalimage, $watermark, 0, 0, 0, 0, $watermarkwidth, $watermarkheight, 100);
//now move the file where it needs to go
if(!file_exists($path_to_medimage_directory)) {
if(!mkdir($path_to_medimage_directory)) {
die("There was a problem. Please try again!");
}
}
imagejpeg($finalimage, $path_to_medimage_directory . $filename);
}
The issue is that the watermark has a transparent background, but it shows up as having a black background on the image. I have seen stuff about alpha blending, etc. but I do not really know what this is. I want to understand what I am doing, as well as fix the problem so that the watermark is transparent as it should be. The real picture should fill the space.
Thanks in advance.
Scott, there are a lot of things that can be going on here.
You need to make sure you saved your PNG using alpha transparency not indexed. Indexed transparency basically says "This color(maybe black) will be displayed as transparent throughout the image." When read by a browser or image editor, it may be transparent, but especially if you're merging it with a JPG, the transparency won't be honored. If you want to understand more, try http://www.idux.com/2011/02/27/what-are-index-and-alpha-transparency/
Make sure you are getting the correct dimensions for both images. See Transparent PNG over JPG in PHP to make sure you're not running into the same issue.
If you are still running into issues, you may want to check here: http://php.net/manual/en/image.examples.merged-watermark.php as it shows how to change the opacity of an image. It may be close to what you are trying to accomplish or might jog another thought.
http://php.net/manual/en/function.imagecopymerge.php:
<?php
$src = imagecreatefromstring(file_get_contents('watermark.png'));
$dest = imagecreatefromstring(file_get_contents('Unmarked/indian_elephant_chasing_bird.jpg'));
// Set the brush
imagesetbrush($dest, $src);
// Draw a couple of brushes, each overlaying each
imageline($dest,
imagesx($src)/2,
imagesy($src)/2,
imagesx($src)/2 ,
imagesy($src)/2,
IMG_COLOR_BRUSHED);
header('Content-Type: image/png');
imagepng($dest);
?>
So I figured it out; instead of using imagecopymerge() I used imagecopy() and it worked fine.
I saw somewhere that there may be a bug with imagecopymerge()that causes this in PHP5.

Image resizing in php? Can't get it to work

I have this code that I have tried creating and don't know what I am doing wrong.
// SET ERROR FLAG
$error = false;
// MAKE SURE FILE IS AN IMAGE
if (!list($width, $height) = getimagesize($_FILES['avatar']['tmp_name'])) {
$error = true;
}
// MAKE SURE FILE COMES FROM FORM
if (!is_uploaded_file($_FILES['avatar']['tmp_name'])) {
$error = true;
}
// MAKE SURE FILESIZE IS NOT OVER 1MB
if (filesize($_FILES['avatar']['tmp_name']) > 1048576) {
$error = true;
}
// TARGER TO SAVE FILE AND CHANGE FILENAME AND FILE TYPE
$target = 'images/avatars/' . md5($user['id']) . '.gif';
// IMAGE RATIO AND RESIZING
$imgRatio = $width / $height;
if ($imgRatio > 1) {
$newWidth = 200;
$newHeight = 200 / $imgRatio;
} else {
$newWidth = 200 * $imgRatio;
$newHeight = 200;
}
$imgResized = imagecreatetruecolor($newWidth, $newHeight);
$newImg = imagecreatefromgif($_FILES['avatar']['tmp_name']);
$newImg = imagecopyresized($imgResized, $newImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
// SUCCESSFULL IMAGE UPLOAD
if (!$error && move_uploaded_file($newImg, $target)) {
echo '<p>Your avatar was uploaded successfully.</p>';
// ERROR UPLOADING IMAGE
} else {
echo '<p>There was an error uploading your avatar.</p>';
}
It always fails I cannot get the resizing to work, even a link to a good tutorial will suffice,
Happy new year!!
I think the problem is that you use GD to open the temporary image file:
$newImg = imagecreatefromgif($_FILES['avatar']['tmp_name']);
$newImg = imagecopyresized($imgResized, $newImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
And then you try to move the temporary avatar file with move_uploaded_file without freeing GD resource and also discarding all the work done with GD (the resizing I mean, and I can add here you have to use resample instaead of resize method).
if (!$error && move_uploaded_file($newImg, $target)) {
The code moves the temporary uploaded file (currently opened by GD and however not physically altered by your GD work, so not resized) to the $target path.
Edit. Now I see more errors with your code. You cannot do:
$newImg = imagecopyresized($imgResized, $newImg, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
Because imagecopyresized do not returns anything but true or false. It simply copy one portion of a source image to a different destination resource. It do not return a resource itself!
Finally. The correct workflow to the what you want to do is:
Check the uploaded file if it's ok for you (and you do it good, it seems).
Create a $img GD resource opening the uploaded file with imagecopyresized.
Create an empty destination resource $newImg with imagecreatetruecolor.
Resize or resample using imagecopyresized or imagecopyresampled to copy source image to destination resource.
Save destination resource into a GIF file using imagegif.
Discard temporary source uploaded image.
You can learn more googling something like php gd resize uploaded images. Tons of tutorial will be one click far from you.
The code itself looks alright, however there could be a number reasons why it fails. Some debug output would be helpful. Some general pointers:
check that the path for the tmp_name is set and readable
check your php settings for post_max_size, it may be set very low or not set at all.
in your code you are only handling gif type images (imagecreatefromgif), you may need to check for the filetype prior to reading from the image resource
check that GD is properly installed in your php installation (phpinfo(); in a php script or php -i from command line should display it as acticated)
That being sad, add some error messages to your output so we can help further.

Black result image problem on BMP image resize using PHP

I have a PHP script to re size image file as below;
$file = "test.bmp";
$ext = pathinfo($file, PATHINFO_EXTENSION);
$info = pathinfo($file);
$file_name = basename($file,'.'.$info['extension']);
$thumbname = "thumb/".$file_name.".".$ext;
$maxh = 200;
$maxw = 200;
$quality = 100;
list($width,$height)=getimagesize($file);
$src = imagecreatefromwbmp($file);
$tmp = imagecreatetruecolor($maxw,$maxh);
imagecopyresampled($tmp,$src,0,0,0,0,200,200,$width,$height);
imagejpeg($tmp,$thumbname,$quality);
imagedestroy($tmp);
The script is suppose to resize a Windows bitmap image to 200x200 thumbnail. But instead, I am getting a black 200x200 image. I am using PHP with Apache in Windows PC. How can I fix this?
.bmp and wbmp are VERY, VERY different file types.
Note the content-type headers:
Content-Type: image/x-xbitmap
Content-Type: image/vnd.wap.wbmp
Calling imagecreatefromwbmp($file) where $file is a .bmp will fail every time.
See this thread for info on how to load a .bmp file. It's not pretty.
As pointed out in PHP imagecopyresampled() docs:
Note:
There is a problem due to palette image limitations (255+1 colors). Resampling or filtering an image commonly needs more colors than 255, a kind of approximation is used to calculate the new resampled pixel and its color. With a palette image we try to allocate a new color, if that failed, we choose the closest (in theory) computed color. This is not always the closest visual color. That may produce a weird result, like blank (or visually blank) images. To skip this problem, please use a truecolor image as a destination image, such as one created by imagecreatetruecolor().
To see if it's the case you can use imageistruecolor() and copy the contents to a new truecolor image before "copyresampling" it:
if( !imageistruecolor($src) ){
$newim = imagecreatetruecolor( $width, $height );
imagecopy( $newim, $src, 0, 0, 0, 0, $width, $height );
imagedestroy($src);
$src = $newim;
}
There is a new opensource project on Github that allows reading and saving of BMP files (and other file formats) in PHP.
The project is called PHP Image Magician.
<?php
//Create New 'Thumbnail' Image
$newImageWidth = 200;
$newImageHeight = 200;
$newImage = imagecreatetruecolor($newImageWidth, $newImageHeight);
$newImageFile = 'output.jpg';
$newImageQuality = 100;
//Load old Image(bmp, jpg, gif, png, etc)
$oldImageFile = "test.jpg";
//Specific function
$oldImage = imagecreatefromjpeg($oldImageFile);
//Non-Specific function
//$oldImageContent = file_get_contents($oldImageFile);
//$oldImage = imagecreatefromstring($oldImageContent);
//Get old Image's details
$oldImageWidth = imagesx($oldImage);
$oldImageHeight = imagesy($oldImage);
//Copy to new Image
imagecopyresampled($newImage, $oldImage, 0, 0, 0, 0, $newImageWidth, $newImageHeight, $oldImageWidth, $oldImageHeight);
//Output to file
imagejpeg($newImage, $newImageFile, $newImageQuality);

php says php made png is invalid

So I have a function that turns a jpeg into a png image resizes it then saves it. Then a bit later i come back to it and use the image in a rotate function. I keep getting errors though. It says uploads/image.png isnt a valid PNG file. The weird thing is that it only does then on php edited png files. If i delete image.png and download a png from the internet name is image.png is works fine as long as i dont run it through the first resize script.
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
if( $this->image_type == IMAGETYPE_JPEG ) {
$imagecreated = imagecreatefromjpeg($filename);
$this->image = $imagecreated;
$extention = pathinfo($filename, PATHINFO_EXTENSION);
$basename = basename($filename, ".".$extention);
$newname = "uploads/".$basename;
imagepng($imagecreated, $newname.".png", 0);
// ....???
function resize($width,$height) {
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height,
$this->getWidth(), $this->getHeight());
$this->image = $new_image;
}
Then i save the file with just a simple
imagepng(etc etc);
I go to the uploads folder and it looks fine. its resized and everything. I also noticed photoshop wont open the edited png either.
Also the line of code that produces the error is here..
$image = imagecreatefrompng('uploads/image.png');
Possible fix is to add a NULL for your filters parameter (the last parameter in imagepng)
ie.
imagepng($image,$file_location,0,NULL);
I can't say this should be needed, but I read a similar case where someone noted they had to do this, may be dependant on the version of libpng or gd lib.

Categories