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

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.

Related

How can I specify a background in Imagemagick mogrify based on the colour of an existing pixel?

I want to use mogrify to set the background colour of a large number of images to be whatever colour is at a specific pixel, to make them square.
The vast majority have a single colour in the image background, or are photos in front of a single colour (so with only slight variations from shadows, etc.).
(The specific purpose in this case is to make the images all the same size and square for StyleGAN2-ADA training, so I want to avoid big "letterbox" rectangles where possible as it would be seen by the discriminator as relevant to the image, where a more faded-in background that approximately matches would be more likely to be ignored. Specifically, I have thousands of pictures of single dolls and action figures from various sources, some of which are "trimmed out" to have a truly solid colour background, others of which are against solid colour tables/walls/etc, for instance, from eBay images and such.)
Since they do not all have the same colour in the image background (the colour in the image, as opposed to the 'background colour' setting as per ImageMagick's jargon), I need to sample a pixel and set the background, but I can't figure out how. I tried things based on methods used to set the whole image to one colour, to no avail.
I have tried:
mogrify -verbose -resize 1024x1024 -gravity center -background 'p{10,10}' -extent 1024x1024 -resize 256x256 *.jpg
and
mogrify -verbose -resize 1024x1024 -gravity center -background "%[pixel:p{10,10}]" -extent 1024x1024 -resize 256x256 *.jpg
and neither works. I can't find any other possibilities in the documentation.
EDITED TO ADD: While testing various commands I came across a way to modify your original command to make it work on ImageMagick versions as far back as IMv6.8.
mogrify -resize 1024x1024 -set background "%[pixel:p{10,10}]" \
-gravity center -extent 1024x1024 -resize 256x256 *.jpg
The significant difference is setting the background color in an unusual way. Instead of the normal option -background <color>, this command uses -set background <color>. Then it behaves as expected using that +10+10 color as the background in the "mogrify" command.
For ImageMagick v7 use magick mogrify instead of just mogrify.
The following was my original answer. The suggestion for IMv6 "convert" may be quite useful for some workflows, but the answer above seems to be the simplest, most direct route.
PREVIOUS ANSWER:
ImageMagick v6 won't do that inline parsing of the color, but there are ways to get the same result, usually with IM's "convert" in a "for" loop in your shell. I don't know which shell you're using so I don't know how you'd write a "for" loop, but running this command inside the loop on each image should give you the results you described...
convert $image -resize 1024x1024 ( +clone -crop 1x1+10+10 ) +swap \
-resize 1024x1024 -gravity center -composite -resize 256x256 $image
That reads in the image, resizes it, makes a clone inside the parentheses, and extracts that pixel at +10+10. After the parentheses that single pixel get resized to a 1024x1024 square. Then setting the gravity to "center" and compositing the input image over that colored square gives you the result you described.

ImageMagick: Distort and Overlay

I have several pictures of a landscape.
Using the ImageMagick CLI on OSX, I would like to distort and overlay them properly.
I have looked for distortion coordinates between several of the pictures and a reference picture. I fail to understand the diference between -distort and +distort and how it plays with +repage. When I use -distort, the output has the desired offset but it's incomplete (it needs to be bigger). When I use +distort, I get the full image but it's missing the offset.
Reading the documentation I understand that I could do without the offset if I did the overlay composition in the same command before the offset information is lost but what's happening is that the distort is being applied to both the reference and the distorted images.
This is the result of using -distort:
This is the result of using +distort:
The offset of the -distort result would work once I apply it as an overlay (here using the composite in a separate command, but it's missing a big chunk of the picture.
When I tried to consolidate it in a single command this is the result I get:
This is the command I'm currently using:
convert base.jpg overlay.jpg
-matte -virtual-pixel transparent -distort Perspective '961,1695 1856,2461 2279,1520 3185,2303 3564,2173 4441,2970 1547,2817 2441,3594'
-compose blend -define compose:args=50,100 -composite result.jpg
I understand I could use parenthesis there but I fail to see where should I put them.
Thanks!
Update: this is the result of the overlay when using +distort either in two steps or in a single step as recommended by Mark.
The solution was to use -flatten instead of -composite.
convert base.jpg \( b.jpg -matte -virtual-pixel transparent +distort Perspective '961,1695 1856,2461 2279,1520 3185,2303 3564,2173 4441,2970 1547,2817 2441,3594' \) -compose blend -define compose:args=100,50 -flatten result.jpg
Turns out that -composite ignores the image offsets whereas -flatten works with layers and uses the offset information.
The suggestion came from this thread: http://www.imagemagick.org/discourse-server/viewtopic.php?t=20157
This is the documentation to flatten (link broken in the discussion above): http://www.imagemagick.org/Usage/layers/#flatten
Not sure I understand the issues, but would suggest you try this (untested):
convert base.jpg \
\( overlay.jpg -matte -virtual-pixel transparent -distort Perspective '961,1695 1856,2461 2279,1520 3185,2303 3564,2173 4441,2970 1547,2817 2441,3594' \) \
-define compose:args=50,100 -compose blend -composite result.jpg
That would mean that the perspective distortion is only applied to the overlay, not the base. So, in the code above, the first line only processes the base image, the second line only processes the overlay, and the final line blends the two.

How come imagemagick output has nasty glitchy squares instead of smooth gradients?

I'm trying to create filters like instagraph (https://github.com/webarto/instagraph), but the output images have nasty square-shaped transitions instead of smooth gradients. Why and how do I fix this?
The command I'm running is this: convert \( /home/trusktr/Pictures/hawaii_aug-2013/test/DSC05767.JPG -auto-gamma -modulate 120,50,100 \) \( -size 4240x2832 -fill rgba\(255,153,0,0.5\) -draw 'rectangle 0,0 4240,2832' \) -compose multiply /home/trusktr/Pictures/hawaii_aug-2013/test/DSC05767.JPG.kelvin.jpg
Here's the input image:
http://ghz.me/oY
And here's the output (notice the sky isn't a gradient any more):
http://ghz.me/oZ
Here's another example.
input image:
http://ghz.me/p0
output image:
http://ghz.me/p1
You can see in the arms some nast discolorization. Why? How do we defeat this evil magic?
Your version of ImageMagick probably contains a bug. I just tried it with the latest version (6.8.7-8) and it created an image without the strange artifacts.

How to add Alpha -channels en masse with ImageMagick?

Suppose a dir with a lot of images, some of them miss the alpha-channel so looking bad against a background. I thought every picture had alpha -channel but some pictures now show white instead of having transparency. How can I add the alpha channels en masse?
Not Working
$ convert imageNoAlpha.png -alpha on imageAlpha.png
This will change white to transparent as in you coment BUT any other white in the image will be transparent as well:
convert input.jpg -background none -transparent white -flatten output.png
Thanks to Bonzo, I was able to get very cool results even without anti-alias! You can see the difference in the eyes with the below picture. I don't know how much you lose information by this but at least I am more able to adjust things, not so easy in anti-aliasing at least for me.
$ convert in.png -background none -fuzz 10% -transparent white -flatten out.png
En masse -approach is probably easiest with a bash -for-loop or use ImageMagick -pkg built for python. I don't know which approach is better, I will leave this here for future answers to improve. Thanks.

ImageMagick on iOS: Blurring and blending an image with itself

I'm trying to take an image, blur it with a 10px radius (both -blur and -gaussian-blur should work fine), then give it a 50% opacity, and finally overlay the blurred transparent image with the original. Here's what I've got so far:
convert sample.png \( sample.png -gaussian-blur 10 -matte -channel A
-evaluate set 50% \) -composite dreamy.png
Here's the original image:
And here is what it should look like after the effect is applied:
However, what I get with the command above just looks very similar to the original. Anyone have any ideas how to achieve the effect I want? If I do what I originally described in an image manipulation program, I get the desired effect, so something is probably wrong with the command I'm using.
Edit:
-adaptive-blur seems to get me closer to the desired effect, but still I'd like to use -blur.
Edit 2:
convert round-face-winslet.jpg \( +clone -blur 0x10 \) -compose Screen -composite round-face-winslet_soft.jpg
...gets me yet closer to the result, but no matter what kind of -compose method I choose, the result still does not look like the desired image. It's either too light or too dark. What should be a simple 50% opacity blended with the underlying original picture, for some reason doesn't want to work...
I think the effect you are looking for can be found in the ImageMagick compose examples in the "Softened Blurring" section.
convert face.png -morphology Convolve Gaussian:0x3 face_strong_blur.png
convert face.png face_strong_blur.png \
-compose Blend -define compose:args=60,40% -composite \
face_soft_blur.png
Looks like this:
An older tutorial on this technique (here) suggests lightening the blurred layer and blending in Multiply mode. I expect that darkening the blurred layer and blending with Screen would also work. Don't use a standard 50/50 blend - it doesn't have the same glowing appearance.
In your sample, the shadows of the processed image are lighter. Multiplying can only make an image darker, so I'm guessing they took the darken-Screen approach.

Resources