Add round corners to a jpeg file - php

I am trying to add round corners to a jpeg file, but the problem is that after adding round corners, I am getting a black background color. Somehow I am not able to change it to any other color (white, transparent, red). It just simply shows black background where the image has rounded corners.
The code that I am using is:
<?php
$image = new Imagick('example.jpg');
$image->setBackgroundColor("red");
$image->setImageFormat("jpg");
$image->roundCorners(575,575);
$image->writeImage("rounded.jpg");
header('Content-type: image/jpeg');
echo $image;
?>
I cannot use png as the jpeg files are huge, about 5 MB, so if I used png, the file size would go up to 26 MB, even though the png adds transparent round corners.
Also the IMagick version that i am using is:
ImageMagick 6.6.2-10 2010-06-29 Q16 http://www.imagemagick.org
Also the output(image generated) will get printed so I don't know if css will work over here.
Sorry, I am trying to actually create a new jpeg file with rounded corners from an already existing jpeg file that doesn't have round corners this is actually a photograph taken from a camera, so there are multiple/too many colors so I can't use gif as well.
Also my site will only just generate the round corner image then afterwards it will get downloaded using a FTP program by the admin of the site and then using a system software will get printed, so in short my website will not be printing the image but rather just generate it

Try this:
<?php
$input = 'example.jpg';
$size = getimagesize($input);
$background = new Imagick();
$background->newImage($size[0], $size[1], new ImagickPixel('red'));
$image = new Imagick($input);
$image->setImageFormat("png");
$image->roundCorners(575,575);
$image->compositeImage($background, imagick::COMPOSITE_DSTATOP, 0, 0);
$image->writeImage("rounded.jpg");
?>

I may get downvoted, but I say let css deal with the corners and take some load off of your server :)
CSS rounded corners.

JPG doesn't have a transparent color(s) (alpha channels) in its palette.
The output image must use either PNG or GIF (or another image format that supports alpha channels).
setImageBackgroundColor is another option if you want an opaque background.
EDIT
Your comment reminds me that you could try to use the command line; shell_exec() will run a command line argument from PHP. The command in the ImageMagick API you'll need to start with is convert example.jpg, and then you can pass flags with the various parameters you want.
Since ImageMagick is already installed, it will work right away. You may need to point your system PATH to the ImageMagick directory where all of the executables are.
There's plenty of questions and forums dedicated to rounded corners with this method so I'll leave that up to you.
Here's a helpful tip though - there is a silly confusion with the convert command, since Windows also has a convert.exe that is rarely used, but will confuse your command line, so make sure you're calling the right convert. ;) To test if it's working, try convert example.jpg example.gif (which should convert your example to a gif).
To get output from your command line, finish all commands with 2>&1 which will pipe cmd output back into PHP.

Related

PHP imagick - Convert eps to jpg but poor quality

I'm trying to convert and resize eps files into jpg. I use php imagick for this.
After converting the quality is very bad.
my eps you can download here:
https://www.file-upload.net/download-14285439/icon.eps.html
my jpg-img
i use this code:
if ( extension_loaded('imagick') ) {
$imagePath = 'icon.eps';
$imagick = new Imagick();
$imagick->setResolution(300, 300);
$imagick->setColorspace(Imagick::COLORSPACE_SRGB);
$imagick->readImage($imagePath);
$imagick->resizeImage(0, 1000, Imagick::FILTER_LANCZOS, 1);
$imagick->setImageResolution(72, 72);
$imagick->setImageCompressionQuality(70);
$imagick->setImageCompression(\Imagick::COMPRESSION_JPEG);
$imagick->setCompressionQuality(70);
$imagick->setImageFormat('jpeg');
$imagick->writeImage('test.jpg');
} else {
echo 'not found';
}
same result with this settings without resize/only convert, but the quality is still bad:
if ( extension_loaded('imagick') ) {
$imagePath = 'icon.eps';
$imagick = new Imagick();
$imagick->setResolution(300, 300);
$imagick->setColorspace(Imagick::COLORSPACE_SRGB);
$imagick->readImage($imagePath);
$imagick->setImageFormat('jpeg');
$imagick->writeImage('test.jpg');
} else {
echo 'not found';
}
i use this version with php 7.2.33:
phpinfo
What is wrong?
As you obviously know ImageMagick uses Ghostscript to render EPS files to JPEG. I would suggest that, rather than use ImageMagick you use Ghostscript directly. This will give you more control over the process than using ImageMagick and will mean that you can post the Ghostscript command line instead of an IM one.
I'm afraid that I have no idea what ImageMagick sends to Ghostscript which makes it rather difficult to offer any suggestions.
In addition you really need to be much more explicit about your problem. What do you actually mean by 'the quality is very bad'. Is this purely subjective or is there some objective criteria you are using ?
The image you've posted doesn't look much like what I see, but since I don't know what command is being used to drive Ghostscript, it may simply be that I am not reproducing your setup exactly.
First note; the nature of your EPS is not really suitable for JPEG compression. JPEG performs best when applied to smoothly varying images, like photographs (JPEG = Joint Photographic Expert Group), it does not work well with large areas of flat colour with sharp edges (which is exactly what you have here), the high frequency component of the sharp edges gives rise to 'ringing' or 'fringing' effects.
When using Ghostscript directly it is possible to alter the JPEG quality. Setting -dJPEGQ=100 will produce the highest quality, trading off the compression (ie the output file will be larger).
In addition your EPS gives its BoundingBox as 20x20 points. So that's 20/72 inch in each dimension. Even at 300 dpi that's going to result in an image which is 84x84 pixels. Pretty small. At 72 dpi you'll get an image which is 20x20 pixels,
It looks to me like you have rendered the EPS at 72 dpi with the default JPEGQ value, the 'poor quality' appears to be nothing more than the well known artefacts produced by JPEG compression. Using that setup with Ghostscript produces something not entirely unlike your posted image (though without the sharp edged corner artefacts). Setting JPEGQ to 100 produces something more sensible. The file produced by the default settings is 3,564 bytes, while the higher quality file is 4,485 bytes.
If it were me I would render to a TIFF file at a decent resolution, say 1200 dpi to give an image 333x333 pixels. Then load that into ImageMagick and resize it to your desired dimensions. Finally export as a JPEG if you require it that way for some reason.
here's a comparison of the output from Ghostscript. On the left is a JPEG produced at 1200 dpi, in the middle is the default quality rendering at 72 dpi and on the right the 72 dpi rendering with JPEGQ set to 100.

PHP Imagick converting SVG without antialiasing

I'm trying to write a PHP function to convert an SVG image without any antialiasing (so that the final PNG is blocky and contains only the colours specified in the SVG).
The command line equivalent is:
convert +antialias /path/to.svg /path/to.png
I'm assuming that I need to use PHP's Imagick::setOption method to pass in "+antialias", but the documentation is very sparse.
The following snippet will write a PNG file, but none of the options prevents antialiased pixels being rendered:
$image = new Imagick();
// None of these have any affect - output image is always antialiased.
$image->setOption('+antialias', true);
$image->setOption('-antialias', true);
$image->setOption('+antialias', 'true');
$image->setOption('-antialias', 'true');
$image->setOption('antialias', true);
$image->setOption('antialias', false);
$image->setOption('antialias', 'true');
$image->setOption('antialias', 'false');
$image->readImage('/path/to.svg');
$image->writeImage('/path/to.png');
Any help would be great, thanks.
That is not a good way to anti-alias a vector file such as SVG. The proper way in command line would be to set the desired density before reading the file and then resize back to compensate for a large magnification when using a large density. So for example
convert -density 288 image.svg -resize 25% image.png
Nominal density (default) is 72. So 288 = 72*4. Thus we resize afterwards by 1/4 = 25%, unless you want a larger output. Then resize by a larger value.
In PHP Imagick, you can create a new Imagick() instance. Then set the desired density. Then read the input SVG. Then resize. Then set the PNG format and save to disk. See setImageResolution for setting the density in Imagick. See https://www.php.net/manual/en/imagick.setimageresolution.php
I don't think what you want is possible, unfortunately. ImageMagick shells out to Inkscape to render SVGs, and Inkscape has no command-line option to disable antialiasing.
https://graphicdesign.stackexchange.com/questions/138075/export-svg-without-anti-aliasing-in-inkscape-1-0-by-command-line
You could render at high resolution and then do nearest-neighbour downsampling. It would reduce the visible antialiasing, but you would still get some colours not in the SVG file.

How to convert CMYK/RGB TIFF to RGB JPEG using PHP IMagick

I have a PHP application which needs to deal with incoming TIFF files. I have neither control nor knowledge over the colorspaces of this TIFFs and the application should store all incoming images as RGB JPEGs.
Problem is, incoming TIFF files are anything: CMYK, RGB, some sort of YCbCr wrapped in sRGB, and so on, and I need to convert them somehow to RGB JPEGs before saving.
I need some sort of a conversion function in PHP which uses IMagick extension which can get any binary TIFF data and convert it to proper RGB JPEG binary data. It needs to handle different colorspaces inside TIFF images correctly. Output format (RGB JPEG) stays the same for any input file.
The following obvious solution converts some CMYK TIFFs correctly, some CMYK TIFFs get inverted colors and YCbCr RGB TIFFs get totally corrupted by red overlay:
$converter = new IMagick();
$converter->setResourceLimit(6, 1);
$converter->readImageBlob($data);
if ($converter->getImageColorspace() != IMagick::COLORSPACE_RGB
&& $converter->getImageColorspace() != IMagick::COLORSPACE_GRAY
) {
$icc_rgb = file_get_contents('sRGB_v4_ICC_preference.icc');
$converter->profileImage('icc', $icc_rgb);
$converter->setImageColorspace(IMagick::COLORSPACE_RGB);
}
$converter->setImageFormat('jpeg');
$converter->setImageCompression(Imagick::COMPRESSION_JPEG);
$converter->setImageCompressionQuality(60);
$converter->resizeImage(1000, 1000, IMagick::FILTER_LANCZOS, 1, true);
$converter->stripImage();
$result = $converter->getImagesBlob();
This solution is taken from there: http://blog.rodneyrehm.de/archives/4-CMYK-Images-And-Browsers-And-ImageMagick.html Obviously, it doesn't work for all colorspaces, because it doesn't detect them reliably. As you can see, it even uses the sRGB_v4 ICC color profile downloaded from it's homepage.
Google finds me one particular solution to the red overlay problem (just one of the conversion screw-ups), but it's only for console and when you know beforehand that you deal with YCbCr images:
convert some.tif -set colorspace YCbCr -colorspace RGB some.jpg
I can live with passthru-ing convert and pass to convert all the magical switches needed, but I suppose I need to detect the source image's colorspace beforehand and call a identify | grep before every convert in an otherwise PHP application is an overkill.
I've experienced this same issue.
It also came up in the imagick forums and the correction was pushed into ImageMagick 6.8.0-4 .
So upgrading should solve this issue. I've upgraded to ImageMagick 6.8.1-9 and haven't encountered this since.

php imagerotate() ruins alpha on png?

I've been bashing my head agains something simple..
// ....all prev code is fine....
$pasteboard =imagecreatetruecolor($imgs['bg']["width"],$imgs['bg']["height"]);
imagealphablending($pasteboard, false);
imagecopyresampled($pasteboard, $imgs['bg']["img"],0,0,0,0,$imgs['bg']["width"],$imgs['bg']["width"],imagesx($imgs['bg']["img"]),imagesy($imgs['bg']["img"]));
imagecopyresampled($pasteboard, $imgs['photo']["img"],20,20,0,0,$imgs['photo']["width"],$imgs['photo']["width"],imagesx($imgs['photo']["img"]),imagesy($imgs['photo']["img"]));
imagesavealpha($pasteboard,true);
//send it out
$out = $pasteboard;
header('Content-type: image/png');
imagepng($out);
//then garbage collection
gives me this:
HORAY!
perfect alpha png composite...
Now I want to rotate it, so instead of the $out=$pasteboard i do this:
imagesavealpha($pasteboard,true);
//rotate it
$out = imagerotate($pasteboard,5,imagecolorexactalpha($pasteboard,255,255,255,50),0);
header('Content-type: image/png');
imagepng($out);
which sadly gives me this:
BOOOO!
Ive tried setting the color like:
imagerotate($pasteboard,5,0x00000000,0);
also the last attr like:
imagerotate($pasteboard,5,0x00000000,1);
new empty images sampled etc etc...
no dice....
Can anyone help?
I'm answering my question simply because I've tried 10-15 suggestions i've seen allover the web all of which offering 'nearly' right solutions but nothing exact, Also I've seen this question posted a few places now, and hopefully if anyone reaches this page in future it would be best to show the solution as the direct answer.
MASSIVE thanks to #cristobal for the help and efforts, if I could vote you up any more I would !
The knack seems to be:
//rotate it
$pasteboard = imagerotate($pasteboard,5,0XFFFFFF00,0); //<-- here must be RRGGBBAA, also last attr set to 0
imagesavealpha($pasteboard, true); // <-- then to save it... dont ask me why..
//send it out
header('Content-type: image/png');
imagepng($pasteboard);
produces this (it has a perfect alpha even though you cant see against the white page):
REALLY not the most fun 5 hrs of my life... hopefully it will stop someone else going through the same pain..
Using the same code above and using a blue color for the third parameter in the imagerotate operation, which will be it used to fill the uncovered zone after the rotation i.e.:
imagerotate($pasteboard, 5, 255);
We get the following image
we see the blue area is the uncovered zone which it fills, while the black color is the to be the border shadow from the image which GD does not seem to handle well along the interpolation used in the rotation.
The same image rotated using the convert for imagemagick. commmand i.e. $> convert -rotate 5 image.png image_rotated.png results in the image below
Clearly GD does not handle alpha colors well when rotating.
If you have access to use the convert commmand using exec or process, you should pipe those image operation to imagemagick instead. GD is a simple image library which has not been updated much the latest years. Otherwise try Imagemagick, Cairo or Gmagick which there are pecl plugins for too http://php.net/manual/en/book.image.php.
Last resort somebody made a function that which uses GD http://www.exorithm.com/algorithm/view/rotate_image_alpha for what you are looking after but the result is not pretty since its a simple linear interpolation:
taken from How to rotate an image in GD Image Library while keeping transparency?. Perhaps if you convert the linear interpolation function to a Bicubic or Quad it will look better.
Note these answers did not work for me but this did.
$destimg = imagecreatefromjpeg("image.png");
$rotatedImage = imagerotate($destimg, 200, 0);
imagesavealpha($rotatedImage, true);
imagepng($rotatedImage,"rotated.png");

PHP IMagick RGB to CMYK inverts?

I'm trying to convert a RGB .gif to a CMYK .gif using IMagick PHP module.
I've wrote this piece of code
$i = new Imagick('mosaique.gif');
$i->setImageColorspace(Imagick::COLORSPACE_CMYK);
$i->setImageFormat('gif');
$i->writeImage('mosaique-cmyk.gif');
But the resultant "mosaique-cmyk.gif" still a RGB... but with inverted colors (O_O)
What am I doing wrong?
EDIT:
I've tried with a .jpg and the image is converted to CMYK but it stills in negative.
EDIT 2:
I've tried to run my script making a .pdf on another server and it works fine.
Are there any known bug in IMagick?
Are there some options to set in the php5 library?
The version that returns me the inverted image is newer than the one that works correctly
WRONG RESULT
PHP 5.3.3
IMagick 3.0.0RC1
ImageMagick 6.6.2
CORRECT RESULT
PHP 5.2.10
IMagick 2.1.1
ImageMagick 6.5.1
The error in fact it's a bug ;)
I reported it, some other has confirmed my fear and now it's assigned to a developer for a fix: http://pecl.php.net/bugs/bug.php?id=22184
At this moment the solution it's to use a different version of the libraries.
GIF is 256-color format aka "indexed." I do not think one can save a gif as cmyk. Each of the 256 colors is an RGB value, but it is not capable of storing the full RGB gamut.
Try this:
$im->stripImage();
$icc_cmyk_profile_path='image_functions/cmyk_icc_profiles/USWebUncoated.icc';
//[http://www.mattbeals.com/icc/][1]
$icc_cmyk = file_get_contents($icc_cmyk_profile_path);
$im->profileImage('icc', $icc_cmyk);
unset($icc_cmyk);
$colorspace=$im->getImageColorspace();
if ($colorspace==12) {
echo "CMYK";
}
$im->stripImage();
$im->writeImage($destination);
$im->clear();
$im->destroy();
see here http://imagemagick.org/Usage/formats/#color_profile
convert cmyk_image.jpg -colorspace
rgb rgb_image.jpg

Categories