ImageMagick: What is this convert-command doing? - php

I'm trying to port a PHP script to Ruby and until now I only used ImageMagick to convert from one file-format to another. Meaning: Yes, I'm an ImageMagick newbie. ;-)
Somewhere inside the PHP script the following code is executed:
$output = array();
$returnValue = 0;
$cmd = 'convert '.$pngFile->path.' -resize 1x1 -alpha on -channel o -format "%[fx:u.a]" info:'
exec($cmd, $output, $returnValue);
Using the ImageMagick documentation for convert I identified the following options:
-resize 1x1 Resize to 1x1 pixels (right?)
-alpha on Activate alpha-channel
-channel o Apply options to the opacity image-channel
My questions:
What does -format "%[fx:u.a]" exactly do? I know that u is a symbol for first image in sequence and a one for alpha. But I don't get what the whole expression really does.
What does info: stand for?
What does this convert-command exactly do?
Thank you very much for your kind help.
Please note: The accepted answer on the following question has a very good answer to this question:
Understanding ImageMagick's convert and translating to Ruby RMagick

Seems like it is computing the average opacity. The info format is a dummy image format that will instruct convert to output image information to stdout (: means stdout) in the format %[fx:u.a]. Resizing to 1x1 is probably a way of averaging.

Related

Error Level Analysis with Imagick PHP - result without color

yesterday I posted about a problem with recreating an Error Level Analysis in PHP with Imagmagick. In this question I found a solution with the command-line interaction and tried to translate it into Imagick and PHP.
The following code was proposed:
convert barn.jpg \( +clone -quality 95 \) -compose difference -composite -auto-level -gamma 1.5 barn_ela.png
In this example, the result should highlight the manipulated parts of the image. So I implemented the following code:
$ELAImageMagick = new Imagick($targetDir . $OriginalImage);
$OriginalImageMagick = new Imagick($targetDir . $OriginalImage);
$ELAImageMagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$ELAImageMagick->setImageCompressionQuality($this->getRequest()->postVar('elaQuality'));
$ELAImageMagick->compositeImage($OriginalImageMagick, Imagick::COMPOSITE_DIFFERENCE, 1,1);
$ELAImageMagick->autoLevelImage();
//Set gamma with a slider in the frontend
$ELAImageMagick->gammaImage($this->getRequest()->postVar('elaSize'));
//save ELA-image into Folder
$ELAImageMagick->writeImage($targetDir . $ELAImage);
Unfortunatly the result does not come close to the desired optic of the result:
The original image (yellow bird has been added in photoshop)
The ELA-Result
Does anyone have an idea, what step I didn't catch quite right and how to solve it? I looked into the documentation and didn't really find any alternatives to this.
Thanks in advance!
You need to first prove that your code works in Imagemagick. But -quality only works for writing a JPG output. So you need to actually save the result of the -quality operation as a JPG and then use it in a second command. Here I just pipe from one convert to another. The first convert actually creates the compressed JPG but just passes it to the second command without writing to disk.
Input:
convert birds.jpg -quality 95 JPG:- | convert birds.jpg - -compose difference -composite -auto-level -gamma 1.5 birds_ela.png
The result I get is:
This is a JPG version of the PNG output since the PNG was too large to post.
However the results from the command line do not match the resulting image you show. So the command is not going to work in Imagick either.
ADDITION:
From what I can see there is no tampering other than possibly the orange bird in the middle. Most of the image is flat or has random noise. The small bird in the middle has a bit brighter texture and so may be an insert.
ADDITION 2
For enhancing edge artifacts, add -geometry +1+1 to my command above just before -compose difference.
convert birds.jpg -quality 95 JPG:- | convert birds.jpg - -geometry +1+1 -compose difference -composite -auto-level -gamma 2 -define jpeg:extent=2000kb birds_ela2.png
Again posting a JPG version for file size issues.
This looks similar to your posted result.

Imagemagick Composite Overwriting File

Good day. I am new to Imagemagick, and I just wanna ask what's wrong with this code
$cmd_for_wm = "composite -gravity southeast watermark.png image.jpg image.jpg;";
exec($cmd_for_wm);
When I run it in the terminal, it is working well, but when I incorporated it in PHP, it doesn't work. Why?
Thanks for you in advance :) Cheers
I've tried your example and it does "die" silently.
This, on the other hand seems to work:
$cmd_for_wm = "composite -gravity southeast watermark.png image.jpg image.jpg;";
passthru($cmd_for_wm);
Very curious indeed. Since the main difference between exec and passthru is the output handling. The later is used for binary data.
My take on this is that passthru correctly allows composite to output the processed image (which is binary data) into the specified file.
For a detailed explanation, please see PHP - exec() vs system() vs passthru()

Combining 2 GraphicsMagick commands into 1 command, like in ImageMagick

I was using ImageMagick to create a new resized image with watermark, with this single command (in PHP):
exec("convert -filter Lanczos {$original_image} -thumbnail {$max_width}x{$max_height} -quality 90 {$watermark} -gravity center -unsharp 2x0.5+0.7+0 -composite {$cached}");
Now I switched to GM and am looking for a way to run 1 command to do the same task. The only way I found was to split it to 2 separate commands:
//create the resized image
exec("gm convert -filter Lanczos {$original_image} -thumbnail {$max_width}x{$max_height} -quality 90 -unsharp 2x0.5+0.7+0 {$cached}");
//apply the watermark and recreate the watermarked image, overwriting the previously resized image
exec("gm composite -quality 90 -dissolve 100 -gravity center {$watermark} {$cached} {$cached}");
Is there a way to combine them into 1 single command and by that maybe also reduce resources & drive usage?
I have received the following reply on this from Bob Friesenhahn, GraphicsMagick Maintainer:
You did not say what version of GraphicsMagick you are using. Modern
versions support a '-compose' option which may be put on the command
line after the input file name to remember the composition algorithm
to use. This composition algorithm is then used if the -mosaic or
-extent operators are used to do a composition. You can also use a
-page option after the input file name to locate the image when it
is composited with prior images in the list. Due to a weakness in
GM's convert command processing, the -mosaic or -extent operators must
be the last command prior to saving the output file. I believe that
ImageMagick's -composite must be a version of -mosaic which adds more
features (e.g. -mosaic might not support gravity but -composite does).
It seems like GraphicsMagick should implement something completely
compatible with ImageMagick's -composite.
Regardless, there is an effective workaround available if you need to
use your existing GM commands.
If you have a modern GraphicsMagick which supports 'gm batch', then
you can use the 'mpr' coder ("Magick Persistent Registry") to remember
intermediate images between commands and you can easily adapt your two
commands to execute with full efficiency using the existing command
lines. This Unix shell example should give you some ideas:
{
echo convert seaworld.jpg mpr:temporary
echo convert mpr:temporary crap.jpg
} | gm batch -prompt off -echo on
convert seaworld.jpg mpr:temporary
convert mpr:temporary crap.jpg
Notice that the output of the first command was saved (as an image
handle as natively used within GraphicsMagick) into 'mpr:temporary'
and then the second command took input from 'mpr:temporary' and wrote
the final output file. You can use arbitrary string arguments to
'mpr:' so you can have several images "in flight".
With this approach you can use 'gm convert' and 'gm composite' in the
same batch command.
I am not sure how one would best access this batch facility from PHP
but if PHP can stream commands to it from a pipe, then it can run for
quite a long time as a co-process to PHP and save considerable compute
time and overhead.

Generate a image thumbnail without stretching it with ImageMagick 6.2.8

Fill Area Flag ('^' flag) is support IM v6.3.8-3But my client's production server has version ImageMagick 6.2.8
Right now in my local server i use this command to generate thumbnail and it works fine:
convert image.jpg -resize "280x210^" -gravity Center -crop "280x210+0+0" thumbnail.jpg
Since my client's production server doesn't support '^' flag how can i generate a thumbnail without using it? (or maybe calculating it manually in PHP or BASH)
Should i use -extent, does it stretch the image?
I also read this and im not sure if ^ flag is for not letting the image stretch because thats what i want, generate a thumbnail without stretching it.
Note: i dont have root access on the server. Im using PHP and BASH to run the commands.
EDIT:
I also don't want any other background colors while resizing and croping.
try
convert image.jpg -background black -resize 280
-gravity center -crop 280x210+0+0 -extent 280x210 image.c.jpg
I found a solution
This is the PHP function i used:
function imgconvert($in,$out,$size){
$size_arr=explode('x',$size);
$resize=( ($size_arr[0]/$size_arr[1]) > 1.775 ? $size_arr[0].'x':'x'.$size_arr[1]);
system("convert \"$in\" -resize $resize -gravity Center -crop \"$size+0+0\" \"$out\"");
}
It seems that if width/height is larger than 1.775 i should use widthX as resize value and if else than i should use Xheight .

ImageMagick and adding a visual watermark

I am currently trying to work with ImageMagick and teaching myself as I go.
I have managed to get images to upload and then be converted size wise, and append some text to them, but I ideally need to append a logo to them.
I have been reading through the documentation via the ImageMagick website but feel I am making stupid mistakes now.
This is the code I have for the ImageMagick command, can anyone shed some light on what I actually need to do to fix this?
$cmd = 'mogrify -composite -disolve 25% -gravity southwest watermark_new.png '.$thefile.' '.$thefile.'';
Thanks for all the help guys.
THIS FIXED THE PROBLEM:
$cmd = 'mogrify -gravity southwest -geometry +30+30 -draw "image Over 0,0 '.$width.','.$height.' \''.$watermark.'\'" '.$thefile;
I dont think you need the mogrify part - the command you're actually looking to use is composite - have you tried:
$cmd = 'composite -disolve 25% -gravity southwest watermark_new.png '.$thefile.' '.$thefile.'';
Theres a number of examples here

Categories