Imagemagick - Getting the usable dimension of an image - imagemagick

I've a process which is creating a file with convert (ImageMagick) based on some parameter, and after that it checks the file and gives back the biggest dimension of it which has real pixels.
The commands look like this:
convert -size 5000x5000 xc:white -font {font} -pointsize {size} -fill black -draw "{some_occassional_additional_parameter}text 200,2500 \"{text}\"" {some_other_occassional_additional_parameter}{temporary_file}
convert {temporary_file}.png -trim +repage -format "%[w]x%[h]\n" info:
. It'll result something like: 526x425
This process runs half a million time per day, and it seems to be a huge bottleneck. I'm looking for a solution which can done this in memory, so not always creating a file and check it, but do it in memory somehow.
If can speed it up just like 50%, that'd be a huge achievement.
Thank You

Not at a computer to test, but change your first command to:
convert -size ... xc:... occasionalstuff -format "%#" info:
Note that you can, and probably should double quote the "%#" especially if you use expressions containing characters of significance to the shell, though it is not strictly necessary in this specific case.

Related

Apply imagemagick transformation on only part of an image, whilst keeping the rest "stock"?

I have many documents per day that are photographed and I need to organise by QR code. The problem is, zbarimg is struggling to pick up many of the QR codes in the photos, so I have been trialling processing them with imagemagick first, using morphology open, thesholding, etc, which has yielded much better results.
The only issue with this is these apply to the whole image, which makes the rest of the file unusable for me, as I deal with the rest of the image based on colours and information which all gets destroyed in the processing. Could anybody give me an example on how I could apply my imagemagick filters to only a part of an image (coordinate based is fine) and leave the rest of the image untouched, so I can continue my process? I will be applying this to all images in a folder, so it's a batch file running this for me in most instances.
I have tried using crops, however this obviously leaves me with only the cropped portion of the image, which doesn't actually help when trying to process the rest of the file.
I'm running my scripts on Windows 11, if that means anything in terms of the solution.
Many thanks!
Tom
EDIT:
Thank you all for the advice given!
I solved my problem using the following:
convert a.jpg ( -clone 0 -fill white -colorize 100 -fill black -draw "polygon 500,300 500,1500 1300,1500 1300,300" -alpha off -write mpr:mask +delete ) -mask mpr:mask +repage -threshold 50% -morphology open square:4 +mask c.jpg
I did post this as an answer, but (and I have no idea why, I'm brand new to stack exchange) my answer was deleted. I used the clone to make the mask with the coordinates needed, then added the threshold and morphology that would make my QR codes more legible!
Thanks again everyone, really helped me out on my journey to figure it out :D
You can use -region to specify a region to process. So starting with this:
You can then specify a region to colorise with blue and then change the region to blur part of the blue and part of the original:
magick swirl.jpg -region 100x100+50+50 -fill blue -colorize 100% -region 100x100+100+100 -blur x20 result.png
The solution using -region may be the most direct. In ImageMagick versions where -region is not supported the same result can usually be achieved by cropping and modifying a clone inside parentheses.
magick swirl.jpg ( +clone -crop 100x100+50+50 -fill blue -colorize 50 ) -flatten result.png
The cloned, cropped, and and modified piece maintains its original geometry, so the -flatten operation puts it back where it was on the input image after the parentheses.

Convert image from one format to another sent to STDOUT

I'd like to convert an image from .jpg to .png. This works just fine:
convert input.jpg output.png
But, I'm trying to have my output go to STDOUT instead of a file, which the manual says to use "-".
I tried using:
convert input.jpg -.png
But it just creates a file called -.png.
Is it possible to convert an image from one format to another and have it go to STDOUT?
Yes, just use a command like this to convert a JPEG to a PNG on stdout:
magick input.jpg PNG:-
These specifiers work on input as well as output. So, if you have a TIFF on stdin and want a 32-bit RGBA PNG on stdout:
magick TIFF:- PNG32:-
You often need these specifiers to ensure a specific filetype when it is not explicitly given, or you want to use a different extension. So, say you have some CCD device that produces RGB data in a raw binary file called image.bin and you want ImageMagick to read it. You can tell ImageMagick the format without having to change the filename (to image.rgb) like this:
magick -size WxH RGB:image.bin result.png
The possible formats are documented here.
The king of all of these formats is MIFF which is guaranteed to be able to hold any and all things you might throw at it, including floating-point values, transparency, masks, concatenated streams... so if you need a format to pass between ImageMagick commands, MIFF is a good option. An example, just to demonstrate because it is not optimal, might to be to concatenate two images from 2 separate ImageMagick commands into a third command that makes an animated GIF:
{ magick -size 100x60 xc:red miff:- ; magick -size 100x60 xc:blue miff:- ; } | magick -delay 80 miff:- result.gif

imagemagick - Restrict elaboration to a region of the image

I need to process a large amount of scans of dot matrix printed documents in order to optimize them for reading with an ocr engine.
I used imagemagick to make sure that there are no white spaces between the points of the matrix, so the ocr engine works much better. The problem is performance, pdfs are scanned at 600dpi and processing takes too long. I would like to limit the processing only to the area affected by the zonal ocr, I tried with the "-region" operator but even if it works, the processing takes the same time.
This is the command used by the windows command line:
convert -density "601.6x600" -units pixelsperinch -monochrome files\1.pdf -region 2000x200+2500+2100 -negate -morphology Thinning "17x17+8+8: -,-,-,-,-,0,0,0,0,0,0,0,-,-,-,-,- -,-,-,-,0,0,0,0,0,0,0,0,0,-,-,-,- -,-,-,0,0,0,0,0,0,0,0,0,0,0,-,-,- -,-,0,0,0,0,-,-,-,-,-,0,0,0,0,-,- -,0,0,0,0,-,-,-,-,-,-,-,0,0,0,0,- 0,0,0,0,-,-,-,-,-,-,-,-,-,0,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,1,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,0,-,-,-,-,-,-,-,-,-,0,0,0,0 -,0,0,0,0,-,-,-,-,-,-,-,0,0,0,0,- -,-,0,0,0,0,-,-,-,-,-,0,0,0,0,-,- -,-,-,0,0,0,0,0,0,0,0,0,0,0,-,-,- -,-,-,-,0,0,0,0,0,0,0,0,0,-,-,-,- -,-,-,-,-,0,0,0,0,0,0,0,-,-,-,-,-" -morphology Thinning "13x13+6+6: -,-,0,0,0,0,0,0,0,0,0,-,- -,0,0,0,0,0,0,0,0,0,0,0,- 0,0,0,-,-,-,-,-,-,-,0,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,1,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,0,-,-,-,-,-,-,-,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,- -,-,0,0,0,0,0,0,0,0,0,-,-" -morphology Close Disk -negate -compress zip r.pdf
P.S. I wanted to post on the imagemagick forum, but I didn't find the link to subscribe ...
Issue is resolved here https://github.com/ImageMagick/ImageMagick/discussions/2841.
the -region param appears to act after the processing of entire file. Fixed using clone, crop, layer and flatten:
magick in.tiff ( +clone -crop 100x100+500+500 -morphology dilate disk ) -layers flatten x2.tiff

Resize an image with 54x54 squares (540x540) to 54x54pixel lossless

I've got an 540x540 image of 54x54 color squares (same sizes).
When I resize it to 54x54px it looks horrible (blurred), shouldn't a resize like this be perfectly done with imagemagick?
is I possible to get it perfect?
I've tested convert source.png -resize destination.png and -adaptive-resize but the result is the same..
I see what your confusion is now... the problem is not that the process is lossy, rather it is because the -resize is doing more sophisticated processing than you want in order to make an attractive job that you would want for, say, photographs. You want a very simple point sampling process which will produce simple blocks of pure, uncombined colour.
I'll make a start image:
magick -size 10x10 xc:red +noise random -scale 540x540 start.png
And scale it down, by taking a point sample in each block:
magick start.png -sample 10x10 small.png
And back up:
magick result.png -scale 540x540 reincarnated.png

How to get the result of an ImageMagick convert command as bitmap data

I am working on a project that will make a jigsaw puzzle from an image and present it to the user as separate pieces in a browser. I have done all the prototyping in Python. At the moment I can produce separate images for each puzzle piece.
As a last step I want to make a nice bevel on the pieces to make them look realistic. I found a ImageMagick convert command to do that just fine:
convert piece.png -alpha extract -blur 0x2 -shade 120x30 piece.png -compose Overlay -composite piece.png -alpha on -compose Dst_In -composite result.png
I execute the command by using os.system, but this is taking way too long to complete.
Can you give me an advice on a solution to execute the ImageMagick processing in the fastest way? I think that would involve executing the processing directly with the ImageMagick libraries, sending it the input bitmap data and receiving the result also as bitmap data. Then I can stream the result to user. The solution does not have to be Python.
Update
I have just been looking at your command again - I kind of assumed it was sensible as you implied you got it from Anthony Thyssen's excellent ImageMagick Usage pages - however I see you are reading the image piece.png three times which it must be possible to avoid by using -clone or -write MPR:save. Let me experiment some more. I haven't got your jigsaw piece to test with, so I am in the dark here, but you must be able to change your command to something like this:
convert piece.png -write mpr:piece \
\( +clone -alpha extract -blur 0x2 -shade 120x30 \) \
-compose Overlay -composite \
mpr:piece -alpha on -compose Dst_In -composite result.png
MPR is a Memory Program Register, or basically a named lump of RAM that ImageMagick can read and write to. There are details and examples here.
Original Answer
Three things spring to mind... which one, or which combination of things, will help depends on the specification of your CPU, memory and disks as well as the sizes of your pieces - none of which I know or can test,
Firstly, if you used the libraries, you would avoid the overhead of creating a new process to run the convert - so that should help, but if your pieces are large and the bottleneck is actually the processing, using the libraries will make little difference.
Secondly, if your images are large, the time to read them in off disk and write them back to disk may be what is killing your performance. To test this, I would create a small RAMdisk and store the images on there and see if that helps. It is a quick and relatively easy test.
Thirdly, I assume you are generating many pieces and you currently do them one after the other in a sequential fashion. If this is the case, I would definitely recommend going multi-threaded. Either do this in your code with your language's threading environment, or try out GNU Parallel which has always been brilliant for me. So, if you were going to do
convert piece1.png -alpha extract ... -composite result1.png
convert piece2.png -alpha extract ... -composite result2.png
convert piece3.png -alpha extract ... -composite result3.png
...
convert piece1000.png -alpha extract ... -composite result1000.png
just either send all those commands to GNU Parallel on its stdin and it will execute them all in parallel on as many cores as your CPU has like this
(
echo convert piece1.png ... -composite result1.png
echo convert piece2.png ... -composite result2.png
echo convert piece3.png ... -composite result3.png
) | parallel
or build the command like this
parallel convert {} -alpha ..... result-{} ::: piece*.png

Resources