Whenever a user uploads a photo using my script, WideImage converts it to JPEG. However, I just noticed that if I upload a PNG picture, with a transparent background, it makes it black instead.
Is there any way to make this white instead?
This is how i save the image:
$img->resizeDown('500', null)->saveToFile('annonce_billeder/'.$bnavn.'.jpeg', 70);
Not really directly. You wnt to read about how transparency is stored in pictures: it is an ordinary color value (any color) that has been marked especially as transparent.
So most likely the color specified in the example pictures you try actually is coded as black and the transparency gets lost whilst converting.
You might have a try to find out if you can detect if there is a color marked as transparent in the incoming picture and then manually change that color to non-transparcy and white before converting the picture.
Might be similar, but I was able to create an empty truecolor image and fill it with its own transparent color before doing any drawing:
$img = WideImage_TrueColorImage::create(100, 100);
$img->fill(0,0,$img->getTransparentColor());
// then text, watermark, etc
$img->save('...');
I assume you'll do something more like:
$img = WideImage::load(<source>);
if( <$img is png> ) {
$img->fill(0,0, $img->getTransparentColor());
}
$img->resizeDown(500, null)->saveToFile('target.jpg', 70);
This is how to do it:
// Load the original image
$original = WideImage::load("image.png");
$original->resizeDown(1000); // Do whatever resize or crop you need to do
// Create an empty canvas with the original image sizes
$img = WideImage::createTrueColorImage($resized->getWidth(),$resized->getHeight());
$bg = $img->allocateColor(255,255,255);
$img->fill(0,0,$bg);
// Finally merge and do whatever you need...
$img->merge($original)->saveToFile("image.jpg");
With some changes (corrections) on Ricardo Gamba's solution code, it does the job...
// Load the original image
$original = WideImage::load("image.png");
$resized = $original->resizeDown('500', null); // Do whatever resize or crop you need to do
$original->destroy(); // free some memory (original image not needed any more)
// Create an empty canvas with the resized image sizes
$img = WideImage::createTrueColorImage($resized->getWidth(), $resized->getHeight());
$bg = $img->allocateColor(255,255,255);
$img->fill(0,0,$bg);
// Finally merge and do whatever you need...
$img->merge($resized)->saveToFile("image.jpg", 70);
Related
I had troubles resizing a PNG and maintaining small file sizes. Solution found here.
When resizing the PNG, however, I ran into problems regarding image quality. As far as I could see, GD uses indexed 8-bit-color palette which distorts text and colors get lost, see:
Original Image
Resized Image with solution given above
Resized Image with a tweak²
²The idea for the tweak I found here in stackoverflow: Create truecolor-image, resize it, and copy it to a new image, so the palette is determined based on the resampled result and the image quality is better as you can see in the image above.
// create new image
$newImageTmp = imagecreatetruecolor($newwidth,$newheight);
// we create a temporary truecolor image
// do the image resizing by copying from the original into $newImageTmp image
imagecopyresampled($newImageTmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
// create output image
$newImage = imagecreate($newwidth,$newheight);
// copy resized truecolor image onto index-color image
imagecopy($newImage,$newImageTmp,0,0,0,0,$newwidth,$newheight);
// write image to buffer and save in variable
ob_start(); // stdout --> buffer
imagepng($newImage,NULL,6);
$newImageToSave = ob_get_contents(); // store stdout in $newImageToSave
ob_end_clean(); // clear buffer
// remove images from php buffer
imagedestroy($src);
imagedestroy($newImageTmp);
imagedestroy($newImage);
Problem: None of both results are satisfactory.
I am quite sure that there must be a way to 1. determine the color palette, and 2. maintain most of the image's colors, so that 3. the PNG looks similar to the original and has an acceptable file size.
Now, I only see going for JPG instead of PNG. But if you know a solution, it would greatly be appreciated if you let me/us know.
Thank you!
All you need is to replace
$newImage = imagecreate($newwidth,$newheight);
With
$newImage = imagecreatetruecolor($newwidth, $newheight);
Output $maxImgWidth = 200;
PHP's fork of GD doesn't have usable palette generation, so you only get PNG32 with vanialla libpng compression.
For small PNG8 with palette use pngquant, e.g. http://pngquant.org/php.html
And then compress it further with advpng or zopfli-png.
Title says JPEG. But I tried PNG. It didn't work.
GD supports imagerotate function.
if (function_exists('imagerotate')) {
echo "test";
}
It outputs the word test. So i assume I have imagerotate function.
$im = imagecreatetruecolor($width + 10, $height + 10);
...
I did some image porcess. I can see the processed image without any problem. But i want to rotate the final image. So i did the following.
imagerotate($im,180,0);
imagepng($im,$png,9);
imagedestroy($im);
But I am still getting the image without rotation.
I even just tried to rotate a image without doing any process. It didn't work too.
You need to assign the rotated image to another variable before create the png.
$rotatedImage = imagerotate($im,180,0);
imagepng($rotatedImage,$png,9);
imagedestroy($rotatedImage);
After several test i decided use scaleimage method of imagick for reduce images, the problem is because i want to get a square image and some of the images to process are rectangular.
To make it square i placed a blank square image as background after the scaled image, this point took me 4 second per image and it's too much.
// Create an image
$scaledimage = new Imagick();
// Set as black
$scaledimage->newImage(800,600,'black');
//Scale the image
$scaledimage->scaleImage(500,500,true); // I need the same aspect
// Create an image
$image = new Imagick();
// Set as white
$image->newImage(500,500,'white');
// compose an image onto another
$image->compositeImage($scaledimage,Imagick::COMPOSITE_DEFAULT,62,0);
// Clone
$scaledimage = clone $image;
Do you known how could i do to make the scaled image square without use this approach.
In PHP I'm trying to process an image, that is, I'm trying to make the surrounding color transparent in a jpg file. I'm using the GD library by the way.
I can directly output the image by converting it into a png using imagecreatefromjpeg and imagepng functions. But I can't find a way to make the specified color transparent. Also, some images have lighter gray artifacts around black graphics, created during saving. Is there any way I can include those as well?
I'm kind of lost. I found some answers to make a color transparent on an image but I don't know how to first convert the image without saving it into the server and then process it.
Any ideas?
EDIT: Here's my code so far. I managed to make a specified color transparent but I can't make it detect the surrounding one yet.
Most of the time images will be closed because they'l be logos or texts, saved in the allowed image formats. So I don't think I will have a major issue with gradients but it would be great if I could manage to manipulate transparency in the surrounding gradients, if any, such as drop shadows.
Is there also any way to detect if the png/gif image is already transparent? My code paints the transparent parts into black for those files now.
$file = 'images/18.jpg';
$specs = getimagesize($file);
if($specs[2] == 1) $img = imagecreatefromgif($file); //gif
elseif($specs[2] == 2) $img = imagecreatefromjpeg($file); //jpg
elseif($specs[2] == 3) $img = imagecreatefrompng($file); //png
else exit('unsupported file type!');
$newimg = imagecreatetruecolor(imagesx($img), imagesy($img));
// create a new image with the size of the old one
imagecopy($newimg,$img,0,0,0,0,imagesx($img),imagesy($img));
// copy the old one
imagedestroy($img);
// free the memory
$white = imagecolorallocate($newimg,255,255,255);
imagecolortransparent($newimg,$white);
// make white pixels transparent
header('Content-Type: image/png');
imagepng($newimg);
imagedestroy($newimg);
// and finally output the new image
You can set the transparent color with the imagecolortransparent function.
I have an image which i am going to be using as a background image and will be pulling some other images from the database that i want to show within this image. So if i am pulling only 1 image, i want the bottom part of the background image to close after the first image, if there are multiple images then i want it close after those images are shown. The problem with not using separate images is that the borders of the images have a design format and i cannot show them separately.
Take a look at this image . The design format of the right and left borders are more complicated than that to just crop them and use them. Any suggestions if there is any dynamic image resizing thing?
Yes there is. Look at the imageXXXX functions; the ones you are particularly interested in are imagecreate, imagecreatetruecolor, imagecreatefrompng, imagecopyresampled, imagecopyresized, and imagepng (assuming you're dealing with PNG images - there's similar load / save functions for jpeg, gif, and a few other formats).
You should try using the GD extension for PHP, especially have a look at imagecopyresized(). This allows you to do some basic image conversion and manipulation very easily.
A basic example that takes two GET parameters, resizes our myImage.jpg image and outputs it as a PNG image:
<?php
// width and height
$w = $_GET['w'];
$h = $_GET['h'];
// load image
$image = imagecreatefromjpeg('myImage.jpg');
// create a new image resource for storing the resized image
$resized = imagecreatetruecolor($w, $h);
// copy the image
imagecopyresized($resized, $image, 0, 0, 0, 0, $w, $h, imagesx($image), imagesy($image));
// output the image as PNG
header('Content-type: image/png');
imagepng($resized);
Have you tried PHPThumb? I used this class often and its pretty clean and lightweight. I used it here.