I'm trying to convert an pdf to a jpeg, trim the whitespaces around the content and resize it to 300x600
In PHP using ImageMagick 6.7.7-10
here's my code:
$im = new \Imagick();
$im->setBackgroundColor("white");
$im->readimage($url);
$im->setImageFormat("jpeg");
$im->trimImage(0);
$im->resizeImage(300, 600, Imagick::FILTER_LANCZOS, 0.9);
$im->writeImage($tmpFilePath);
$im->clear();
$im->destroy();
here is the PDF
http://cs1.fuman.de/file.php/1AOrL6-PzT71Z-dk0000-CsjquC
and here the resulting JPG
http://cs1.fuman.de/file.php/1AOrL0-kWAl8P-ml0000-xAhOiw
Does anyone know, what's going wrong here?
Thanks in advance
JD
I don't know why the background color is being ignored. I think it's to do with JPEG not having a concept of a 'background' colour, and so when the image is converted from having alpha to not having alpha, bad things happen.
I suggest using this code:
$imagick = new \Imagick();
// Make the image be large when read from PDF so have decent quality later
$imagick->setResolution(92, 92);
// only use the first page of the PDF
$imagick->readimage("./orig.pdf[0]");
// Make a white background imge
$canvas = new Imagick();
$canvas->newPseudoImage(
$imagick->getImageWidth(),
$imagick->getImageHeight(),
'canvas:white'
);
// Need to use png format to keep alpha channge
$imagick->setImageFormat('png');
// Composite our image, into the white background
$canvas->compositeImage($imagick, \Imagick::COMPOSITE_ATOP, 0, 0);
$canvas->resizeImage(300, 600, Imagick::FILTER_LANCZOS, 1);
$canvas->setImageFormat('png');
$canvas->writeImage("output.png");
Related
I want to merge a transparent PNG into another Image, but the Border of the PNG will not change to Transparent as a want.
<?
$s1= new Imagick('img.jpg');
$s2= new Imagick('img2.jpg');
$s2->setImageFormat ('png');
$s2->vignetteImage(20, 20, 40, - 20);
$s2->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$s1->compositeImage($s2, Imagick::COMPOSITE_DEFAULT,120,120, Imagick::CHANNEL_ALPHA);
You just need to set the background to transparent on the original JPEG image.
<?
$s1= new Imagick('img.jpg');
$s2= new Imagick('img2.jpg');
$s2->setImageFormat ('png');
$s2->setImageBackgroundColor("transparent"); // <= Here
$s2->vignetteImage(20, 20, 40, - 20);
$s2->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$s1->compositeImage($s2, Imagick::COMPOSITE_DEFAULT,120,120, Imagick::CHANNEL_ALPHA);
If there's still issues, it might be worth ensuring the alpha channel of the PNG is enabled.
$s2->setImageMatte(TRUE);
I have a simple watermark script which works well, but it seems adobe sRGB images lose color quality.
Running a watermark command via shell/imagemagick works great - no color quality lost.
Using imagick, however, dulls the color.
Here is the series of commands I use:
$image = new Imagick();
$image->readImage($this->source_path);
$watermark = new Imagick();
$watermark->readImage($this->watermark_path);
// how big are the images?
$iWidth = $image->getImageWidth();
$iHeight = $image->getImageHeight();
$wWidth = $watermark->getImageWidth();
$wHeight = $watermark->getImageHeight();
// calculate the position
$x = ( $iWidth - $wWidth ) / 2;
$y = ( $iHeight - $wHeight ) / 2;
//we have to make the transparency go to white, or it will become an awefull black color in jpeg version
$white = new Imagick();
$white->newImage($image->getImageWidth(), $image->getImageHeight(), "white");
if ($image->getImageColorspace() == Imagick::COLORSPACE_SRGB) {
$watermark->setColorspace(imagick::COLORSPACE_RGB);
$white->setColorspace(imagick::COLORSPACE_RGB);
}
$white->compositeimage($image, Imagick::COMPOSITE_OVER, 0, 0);
//now apply watermark
$white->compositeImage($watermark, imagick::COMPOSITE_OVER, $x, $y);
//save
$white->writeImage($this->destination);
//save memory
$image->destroy();
$white->destroy();
I made a half-educated assumption that if I convert the other two elements (the white background, and the png overlay) to sRGB, nothing would be lost. I did that with this segment here:
if ($image->getImageColorspace() == Imagick::COLORSPACE_SRGB) {
$watermark->setColorspace(imagick::COLORSPACE_RGB);
$white->setColorspace(imagick::COLORSPACE_RGB);
}
...Still no shrimp Lieutenant Dan...
Is there any possible way around this issue? Ideally I'd like to use the shell commands, but I'd like to perfect the imagick version for those who do not have shell access in their environments.
I found the solution here: http://www.php.net/manual/ru/imagick.compositeimage.php (was like a scavenger hunt!)
The solution as stated in above link:
You might need to set the colorspace the same when composing two
images over each other
<?php
//Creating two Imagick object
$first = new Imagick('first.jpg');
$second = new Imagick('second.jpg');
// Set the colorspace to the same value
$first->setImageColorspace($second->getImageColorspace() );
//Second image is put on top of the first
$first->compositeImage($second, $second->getImageCompose(), 5, 5);
//new image is saved as final.jpg
$first->writeImage('final.jpg');
?>
i'm working on creating one PNG image from two others.
Image A and B have the same dimensions, they are both 200x400px. The final image the same.
I'm using the GD library with PHP.
So my idea was to create a PNG-24 from my original PNG-8, then use color transparency and finally copy the second image into
this new PNG-24. The problem appears in the first step anyway, when going from PNG-24 to PNG-8 with color transparency:
This is to get the original PNG-8 and it's dimensions:
$png8 = imagecreatefrompng($imageUrl);
$size = getimagesize($imageUrl);
Now i create a new PNG and fill it's background with a green color (not present in the images):
$png24 = imagecreatetruecolor($size[0], $size[1]);
$transparentIndex = imagecolorallocate($png24, 0x66, 0xff, 0x66);
imagefill($png24, 0, 0, $transparentIndex);
This is for making the green color transparent:
imagecolortransparent($png24, $transparentIndex);
Then i copy the png8 into the PNG-24:
imagecopy($png24, $png8, 0, 0, 0, 0, $size[0], $size[1]);
So here's the problem: the original PNG-8 looks good, but it has a green border surrounding the shape within the original image. It's difficult to explain really. Seems like some part of the green background is left in the remaining PNG.
What can i do?
thanks in advance
best regards,
Fernando
I had some problems with png transparency before and was able to solve them with this pattern:
// allocate original image to copy stuff to
$img = imagecreatetruecolor(200, 100);
// create second image
$bg = imagecreatefrompng('bg.png');
// copy image onto it using imagecopyresampled
imagecopyresampled($img, $bg, 0, 0, 0, 0, 200, 100, 200, 100);
imagedestroy($bg);
// create third image
// do same routine
$fg = imagecreatefrompng('fg.png');
imagecopyresampled($img, $fg, 50, 50, 0, 0, 50, 50, 50, 50);
imagedestroy($fg);
// output image
imagepng($img);
imagedestroy($img);
I think the only difference between mine and yours is imagecopy() vs. imagecopyresampled(). I seem to remember having problems with that though it was quite a while ago. You can see an example of an image I use this pattern on here: http://www.ipnow.org/images/1/bggrad/bg4/yes/TRANSIST.TTF/8B0000/custombrowserimage.jpg (I allocate a blank image, copy the background image in, copy the overlay with transparency in)
This one is empty image before writing
Here is my code
<?php
function LoadJpeg($imgname)
{
$im = #imagecreatefromjpeg($imgname);
$grey = imagecolorallocate($im, 255, 255, 0);
// The text to draw
$text = 'http://www.stackoverflow.com';
// Replace path by your own font path
$font = 'CONSOLA.TTF';
list($width, $height) = getimagesize($imgname);
// wants to know how to use this width/height dynamically //
imagettftext($im, 20, 45, 200, 450, $grey, $font, $text);
return $im;
}
header('Content-Type: image/jpeg');
$img = LoadJpeg('Blue_hills.jpg');
imagejpeg($img);
imagedestroy($img);
?>
Image after writing text on it
What I want is vertically and horizontally center the text on 45 degree. Please help me on this. Thanks for you all.
Use the imagettfbbox function to retrieve the dimensions the text rendering would require. Then use that information to calculate the x,y coordinate you should target within the destination image for the text to be centered respective to the width/height.
I know very little about PHP (I'm making this up as I go along).
I'd recommend making a new square image, setting it to have a transparent background with imagecolortransparent(). Then write the text to the transparent image.
Next I'd try using imagecopyresized() to copy and scale the text to the new window. Use the minimum of the original's height and width for the destination size. The offset would be something like (max($width, $height)-min($width, $height))/2. Apply the offset to whichever dimension is greater.
how is it possible to save my image, created with gd, as an png-8?
it saves as gif with transparent channel well - but I want to use png-8.
Best Regards,
Beerweasle
Using imagesavealpha() and a transparent bg color should do the trick...
Based on dfilkovi's code:
<?php
// Create a new true color image
$im = new imagecreatetruecolor(100, 100);
// Fill with alpha background
$alphabg = imagecolorallocatealpha($im, 0, 0, 0, 127);
imagefill($im, 0, 0, $alphabg);
// Convert to palette-based with no dithering and 255 colors with alpha
imagetruecolortopalette($im, false, 255);
imagesavealpha($im, true);
// Save the image
imagepng($im, './paletteimage.png');
imagedestroy($im);
?>
#Sonny
false assumption: PNG of any bit depth can have transparency. It is recorded in the tRNS chunk of the png image (except for truecolor ones) cf format definition
cf www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.tRNS
idem www.w3.org/TR/PNG-Chunks.html#C.tRNS
The difference is how it is recorder: RGBA has a unique record per pixel, with 4 values (3 colors and 1 alpha channel), where "paletted" PNG records alpha channel in its own chunk.
Fireworks is very good at it.
Examples:
http://www.libpng.org/pub/png/pngs-img.html
I think this could help you.
http://roseindia.net/tutorial/php/phpgd/About-transparent.html
<?php
// Create a new true color image
$im = new imagecreatetruecolor(100, 100);
// Convert to palette-based with no dithering and 255 colors
imagetruecolortopalette($im, false, 255);
// Save the image
imagepng($im, './paletteimage.png');
imagedestroy($im);
?>
this should make 8bit png
Building on dfilkovi's solution, have you tried using imagesavealpha() to save the full alpha channel information?
I had to add the line imagecolortransparent($im, $alphabg); to the following code (taken from previous answer) for this to work:
// Fill with alpha background
$alphabg = imagecolorallocatealpha($im, 0, 0, 0, 127);
imagecolortransparent($im, $alphabg);
imagefill($im, 0, 0, $alphabg);
// Convert to palette-based with no dithering and 255 colors with alpha
imagetruecolortopalette($im, false, 255);
imagesavealpha($im, true);
// Save the image
imagepng($im, './paletteimage.png');
imagedestroy($im);
?>