Compress PNG files in PHP - php

I am generating PNG file with cairo extension of PHP. The image contains a background and a text. Now I want to compress these images by PHP after its generated by cairo. Is there any library to do this?
I found pngcrush tool. But its a command line tool. I dont want to invoke system call. If there is not PHP solution a C solution would do. In that case I'll make a PHP extension.
I have read this related question. But there is no answer in it.

You can use imagepng() ...
//If you don't already have a handle to the image and it's just on the file system...
$im = imagecreatefrompng("yourGenerateFile.png");
$quality = 5; //0 - 9 (0= no compression, 9 = high compression)
imagepng($im, 'file/to/save.png', $quality); //leave out filename if you want it to output to the buffer
imagedestroy($im);

I would take a look at PngOptimizer. You can get the source for it at the bottom of the page, and it has a separated CLI version too.
Only problem is that source is C++ , not ANSI C. I have never made a PHP extension, so i don't know if it makes a difference.

For C code take a look at ImageMagick. It looks like there is a PHP extension too.

Related

PHP Test if Image is Interlaced

I have a folder that will consist of hundreds of PNG files and I want to write a script to make them all interlaced. Now, images will be added to that folder over time and processing all the images in the folder (wether their interlaced or progressive) seems kinda silly.
So I was wondering, is there any way to use PHP to detect if an image is interlaced or not that way I can choose wether to process it or not.
Thanks heaps!
You can also take the low-level approach - no need of loading the full image, or to use extra tools or libraries. If we look at the spec, we see that the "interlaced" flag it's just the byte 13 of the iHDR chunk, so we have to skip 8 bytes from the signature, plus 8 bytes of the iHDR Chunk identifier+length, plus 12 bytes of the chunk... That gives 28 bytes to be skipped, and if the next byte is 0 then the image is not interlaced.
The implementation takes just 4 lines of code:
function isInterlaced( $filename ) {
$handle = fopen($filename, "r");
$contents = fread($handle, 32);
fclose($handle);
return( ord($contents[28]) != 0 );
}
BTW, are you sure you want to use interlaced PNG? (see eg)
I think ImageMagick could solve your problem.
http://php.net/manual/en/imagick.identifyimage.php
Don't know if all the attributes are returned, but if you look at the ImageMagick tool documentation you can find that they can spot if an image is interlaced or not.
http://www.imagemagick.org/script/identify.php
At worst you can run the command for ImageMagick via PHP if the ImageMagick extension is not installed and parse the output for the "Interlace" parameter.

Add round corners to a jpeg file

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.

Powerpoint PPT to JPG or PNG Image conversion using PHP

I need to convert single Powerpoint (PPT) slides/files to JPG or PNG format on linux but haven't found any way of doing so successfully so far. I have heard that it can be done with open office via php but haven't found any examples or much useful documentation. I'd consider doing it with python or java also, but I'm unsure which route to take.
I understand that it can be done using COM on a Windows server but would really like to refrain from doing so if possible.
Any ideas/pointers gratefully received. (And yes, I have searched the site and others before posting!)
Thanks in advance,
Rob Ganly
Quick answer (2 steps):
## First converts your presentation to PDF
unoconv -f pdf presentation.ppt
## Then convert your PDF to jpg
convert presentation.pdf presentation_%03d.jpg
And voilá.
Explaning a little more:
I had already follow in the same need. Convert a powerpoint set of slides into a set of images. I haven't found one tool to exactly this. But I have found unoconv which converts libreoffice formats to other formats, including jpg, png and PDF. The only drawback is that unoconv only converts one slide to a jpg/png file, but when converting to PDF it converts the whole presentation to a multiple page PDF file. So the answare were convert the PPT to PDF and with imagemagick's convert, convert the multiple page PDF to a set of images.
Unoconv is distributed within Ubuntu distribution
apt-get install unoconv
And convert is distributed with the imagemagick package
apt-get install imagemagick
In my blog there is an entry about this
This can be done from PHP using a 3d party library (Aspose.Slides). It will work on both .ppt and .pptx, and it's lightning fast.
Here is the relevant piece of code in PHP:
$runtime->RegisterAssemblyFromFile("libraries/_bin/aspose/Aspose.Slides.dll", "Aspose.Slides");
$runtime->RegisterAssemblyFromFullQualifiedName("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing");
$sourcefile = "D:\\MYPRESENTATION.ppt";
$presentation = $runtime->TypeFromName("Aspose.Slides.Presentation")->Instantiate($sourcefile);
$format = $runtime->TypeFromName("System.Drawing.Imaging.ImageFormat")->Png;
$x = 0;
/** #var \NetPhp\Core\NetProxyCollection */
$slides = $presentation->Slides->AsIterator();
foreach ($slides as $slide) {
$bitmap = $slide->GetThumbnail(1, 1);
$destinationfile ="d:\\output\\slide_{$x++}.png";
$bitmap->Save($destinationfile, $format);
}
$presentation->Dispose();
It does not use Office Interop (which is NOT recommended for server side automation) and is lightining fast.
You can control the output format, size and quality of the images. Indeed you get a .Net Bitmap object so you can do with it whatever you want.
The original post is here:
http://www.drupalonwindows.com/en/blog/powerpoint-presentation-images-php-drupal-example

php get original image type [duplicate]

I have a sever which people can upload files to. The problem is that some of the filenames are mangled (dont have any extension) and so I cannot immediately determine file type. This question is two part: for the files which do have filenames what is the best way to determine whether or not it is an image? (Just a big long if/else if list?) Secondly, for the files which dont have extensions, how can I determine if they are images?
You can use exif_imagetype()
<?php
$type =exif_imagetype($image);
where $type is a value
IMAGETYPE_GIF
IMAGETYPE_JPEG
IMAGETYPE_PNG
IMAGETYPE_SWF
IMAGETYPE_PSD
IMAGETYPE_BMP
IMAGETYPE_TIFF_II (intel byte order)
IMAGETYPE_TIFF_MM (motorola byte order)
IMAGETYPE_JPC
IMAGETYPE_JP2
IMAGETYPE_JPX
IMAGETYPE_JB2
IMAGETYPE_SWC
IMAGETYPE_IFF
IMAGETYPE_WBMP
IMAGETYPE_XBM
IMAGETYPE_ICO
From the manual:
When a correct signature is found, the appropriate constant value will be returned otherwise the return value is FALSE. The return value is the same value that getimagesize() returns in index 2 but exif_imagetype() is much faster.
You can use getimagesize
It does not require the GD image library and it returns same information about image type.
http://it2.php.net/manual/en/function.getimagesize.php
If you have the GD2 extension enabled, you could just use that to load the file as an image, then if it returns invalid you can catch the error and return FALSE, otherwise return TRUE.
You have two options here, one's simple and pre-built with some shortfalls, the other is complex and requires math.
PHP's fileinfo can be used to detect file types based on the file's actual header information. For instance, I just grabbed your gravitar:
But the actual code is this:
‰PNG
IHDR szzô
IDATX…­—OL\UÆZÀhëT)¡ c•1T:1‘Š‘.Ú(]4†A“ÒEY˜à.................................
So, even without the file name I could detect it quite obviously. This is what the PHP Fileinfo extension will do. Most PNG and JPG files tend to have this header in them, but this is not so for every single file type.
That being said, fileinfo is dead simple to use, from the manual:
$fi = new finfo(FILEINFO_MIME,'/usr/share/file/magic');
$mime_type = $fi->buffer(file_get_contents($file));
Your other option is more complex and it depends on your own personal ambitions, you could generate a histogram and profile files based on their content.
Something like this looks like a GIF file:
And something like this looks like a TIFF file:
From there you'd need to generate a model over multiple types of files for what the histogram of each type should be, and then use that to guess. This is a good method to use for files that don't really have those "magic headers" that can be read easily. Keep in mind, you'll need to learn some math and how to model an average histogram function and match them against files.
You can try to load the image into PHP's GD library, and see if it works.
$file = file_get_contents('file');
$img = imagecreatefromstring($file);
if($img === FALSE){
// file is NOT an image
}
else{
// file IS an image
}
Look at image magic identify. http://www.imagemagick.org/script/identify.php
The php wrapper is here: http://www.php.net/manual/en/function.imagick-identifyimage.php
Or if you just want to validate that it's an image (and don't care about the meta data): http://www.php.net/manual/en/function.imagick-valid.php
exif_imagetype() might work
make sure you have exif enabled.
Try looking at exif_imagetype
If you need a fast solution, use imagesx() and imagesy(). There is also a fast way to check large image file dimensions, by reading just a small amount of data from the file header. Explained in more detail in the following url:
http://hungred.com/useful-information/php-fastest-image-width-height/
You can use the Fileinfo extension:
http://www.php.net/manual/en/function.finfo-file.php
finfo_file() uses magic bytes and does not have to load the whole image into memory. The result is a string with the corresponding MIME type, e.g.:
text/html
image/gif
application/vnd.ms-excel
The type of the image is typically going to be able to be inferenced from the header information of the file.
For the first question is extension is known you could use the PHP function in_array() Documentation

ImageMagick failing to convert to JPG

We recently installed the latest version of ImageMagick onto our Linux server. I seem to be having issues performing the most basic of tasks.
I am running this command line:
/usr/bin/convert /location/to/source/design.ai /location/to/save/output.jpg
Unfortunatly is saves design.jpg as an illustrator file (if I rename the file to output.ai it opens). Even if I do this:
/usr/bin/convert /location/to/source/design.ai -rotate 90 /location/to/save/design.jpg
It rotates the file and saves again as an illustrator document. This happens with all filetypes (e.g. png, bmp, etc...)
It appears ImageMagick cannot figure out what I want it converted to and just saves as the same file type.
Any ideas on fixing this?
Regards:
John
(Yes, McKay is properly right. This question would be better placed at serverfault.)
But I have an idea. By doing 'convert' only one gets a hint at the bottom:
To specify a particular image format, precede the filename
with an image format name and a colon (i.e. ps:image) or specify the
image type as the filename suffix (i.e. image.ps).
Perhaps convert gets confused by the path given.
So you could try this:
convert /location/to/source/design.ai output.jpg
or
convert /location/to/source/design.ai jpg:/location/to/save/output.jpg
Regards
Sigersted

Categories