I'm trying to draw a partially transparent PNG image on another image I created in my script, but it behaves really strange. I'm using imagecopymerge because I want to use different opacity values, but when I do this, the output looks like this:
There must be some problem when processing the image. the yellow parts aren't even visible in the png file. Everything but the black parts are transparent.
I saved the image in photoshop and it looks ok when I just use imagecopy or something.
here are the relevant parts of the script:
$imgLogoBg = file_exists($logoBgImgFile)?imagecreatefrompng($logoBgImgFile):null;
$image = imagecreatetruecolor(imagesx($imgBase), imagesy($imgBase));
imagefill($image, 0,0, imagecolorat($imgBase,0,0));
imagecopymerge( $image, $imgLogoBg,
0,0,
0,0, imagesx($imgLogoBg), imagesy($imgLogoBg),50);
imagepng($image);
I can't figure out what the problem is. when I use another image the result is similar.
Related
We're using a CMS with WideImage built in and no scope to change this, however we've come up against a situation where we need to produce 300x300 images.
However the images that are uploaded at approx 100x100 in jpg and png format with various levels of transparency.
I'm trying to create a 300x300 canvas, and place the 100x100 image inside of it - however I want both the canvas to remain transparent, and the image placed on top to keep its transparency.
I've got
$image = WideImage::loadFromFile( $this->local_path );
$canvas = WideImage::createTrueColorImage(300, 300);
$canvas_bg = $canvas->allocateColor(255, 255, 255);
$canvas->fill(0, 0, $canvas_bg);
$resized_image = $canvas->merge($image);
However this obviously just adds a white background to the canvas, I cant figure out from their documentation how to make it transparent.
Thanks
How about:
$image = WideImage::loadFromFile($this->local_path);
$resized_image = $image->resizeCanvas(300, 300, 0, 0);
You can specify the X and Y location of the image within the new canvas as well as its width and height. $image->resizeCanvas(300, 300, "center", "center") works quite well.
I've been trying to get transparency to work with my application (which dynamically resizes images before storing them) and I think I've finally narrowed down the problem after much misdirection about imagealphablending and imagesavealpha. The source image is never loaded with proper transparency!
// With this line, the output image has no transparency (where it should be
// transparent, colors bleed out randomly or it's completely black, depending
// on the image)
$img = imagecreatefromstring($fileData);
// With this line, it works as expected.
$img = imagecreatefrompng($fileName);
// Blah blah blah, lots of image resize code into $img2 goes here; I finally
// tried just outputting $img instead.
header('Content-Type: image/png');
imagealphablending($img, FALSE);
imagesavealpha($img, TRUE);
imagepng($img);
imagedestroy($img);
It would be some serious architectural difficulty to load the image from a file; this code is being used with a JSON API that gets queried from an iPhone app, and it's easier in this case (and more consistent) to upload images as base64-encoded strings in the POST data. Do I absolutely need to somehow store the image as a file (just so that PHP can load it into memory again)? Is there maybe a way to create a Stream from $fileData that can be passed to imagecreatefrompng?
you can use this code :
$new = imagecreatetruecolor($width, $height);
// preserve transparency
imagecolortransparent($new, imagecolorallocatealpha($new, 0, 0, 0, 127));
imagealphablending($new, false);
imagesavealpha($new, true);
imagecopyresampled($new, $img, 0, 0, $x, 0, $width, $height, $w, $h);
imagepng($new);
imagedestroy($new);
It will make a transparent image for you. Good Luck !
Blech, this turned out to ultimately be due to a totally separate GD call which was validating the image uploads. I forgot to add imagealphablending and imagesavealpha to THAT code, and it was creating a new image that then got passed to the resizing code. Which should probably be changed anyway. Thanks very much to goldenparrot for the excellent method of converting a string into a filename.
Do I absolutely need to somehow store the image as a file (just so that PHP can load it into memory again)?
No.
Documentation says:
You can use data:// protocol from php v5.2.0
Example:
// prints "I love PHP"
echo file_get_contents('data://text/plain;base64,SSBsb3ZlIFBIUAo=');
I have lots of jpeg images that are oversized (height, width), all with different sizes and different aspect ratios.
I'm showing them from a database like this:
<img src="<?php echo $img1; ?>" width="300" height="400">
What I'd like to have is some kind of php function to display a cropped version of the image like this:
cropjpeg('$img1');
For example, if the image is 600 W, 700 H, have php or GD show a cropped version around 300 W, 400 H starting from the top left hand of the image.
Some caveats:
I can't use CSS to do faux cropping. If you download this cropped image, it needs to be just that, the smaller cropped version.
I don't really want to create and save a new image, so I guess I need this to work "on the fly"
I tried imagecreatefromjpeg and imagejpeg, but it seems as though header('Content-Type: image/jpeg'); is not the right answer since there is more on the html page than just this 1 image
There is a lot of traffic on the site, so it has to tread lightly
Here's the best I found so far, but it uses the header('Content-Type: image/jpeg');
<?php
function cropjpeg($img, $x, $y, $width, $height,$grade=5)
{
// Create image instances
$src = imagecreatefromjpeg($img);
$dest = imagecreatetruecolor(400, 300);
// Copy
imagecopy($dest, $src, 0, 0, 20, 13, 400, 300);
// Output and free from memory
header('Content-Type: image/jpeg');
imagejpeg($dest);
imagedestroy($dest);
imagedestroy($src);
}
cropjpeg('images/bikini.jpg');
?>
Any ideas?
You cannot crop an image in the actual html page as it needs to be processed, that's if you don't want to save it on disk.
You can dump the crop script in a single PHP file with headers and call from HTML the script with path eg:
<img src="http://www.example.org/crop.php?i=bikini.jpg&x=13&y=20&w=400&h=300" alt="" />
and in script you can use
<?php
header('Content-Type: image/jpeg');
function cropjpeg($img, $x, $y, $width, $height,$grade=5) {
//......................
imagecopy($dest, $src, 0, 0, $x, $y, $width, $height);
//......................
}
cropjpeg('images/'.$_GET['i'], (int)$_GET['x'], (int)$_GET['y'], (int)$_GET['w'], (int)$_GET['h']);
?>
You should consider the aspect ratio, and search for a better crop script, you don't have to reinvent the wheel.
Use mod_rewrite to send requests for the relevant image file paths to a PHP script, which does the cropping and sends the image data back in response. It looks like a normal image tag on the page, but the images are really being served by your separate script.
The only issue is that you simultaneously don't want to save the cropped files, but have a lot of traffic so want to "tread lightly". You can't have both ways. If you don't want to re-crop the images on every request, you'll need to save the cropped versions so you can re-serve them on future requests.
Here is a page with a very complete tutorial with everything you need to do this using ajax included
crop with jquery and php
[http://www.skillcorp.com.ve][2]
[2]: http://www.skillcorp.com.ve here also more info relational
I wonder if it is possible to have "opacity" effect when drawing images on top of other images with the PHP GD extension? Are there any built-in functions that can get the results I want or do I have to go for my own implementation using imagesetpixel way?
A pseudo-code to illustrate what I am trying to do right now:
// Background image
$image_bg = imagecreatetruecolor(100, 100);
imagesavealpha($image_bg, true);
// Making background image fully transparent
imagefill($image_bg, 0, 0, imagecolorallocatealpha($image_bg, 0, 0, 0, 127));
// Now the actual image I want to draw with opacity (true color PNG)
$image = imagecreatefrompng(...);
// Drawing with 50 "merge" value
imagecopymerge($image_bg, $image, ..., 50);
The trouble with above code is that imagecopymerge will not respect background image alpha value and will merge the image with the background as if it was opaque black color (the resulting image will not be 50% transparent).
Edit: I ended up implementing my own function using imagecolorat and imagesetpixel way.
Take a look at imagecolortransparent() and imagealphablending() (or this question).
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.