I'd like to use Pov-Ray to generate pictures that can be used in a website on any background color. The pictures need to have a transparent background, but with reflection and shadows cast on a transparent plane surface.
In Pov-Ray (3.7), you can set the background transparent by setting Output_Alpha=True in the povray.ini file and outputting as a png file.
You can even get transparent reflective surfaces by using the color Clear on a plane (or any other object). But if you set the color of an object to Clear, no shadows are cast on it.
Is it possible to cast shadows on transparent objects?
You could render the shadows and objects separately and merge the resulting images as shown here.
The technique suggested by m13r produces very nice renderings, but it requires 3 rendering passes and a lot of changes to the scene for each. This takes time and requires quite a bit of setup.
A simpler and honestly for some cases better result can be obtained with just two passes. Set both your background and ground plane to white, render, set them to black, render again. Lets say you toggle the setting here and generate two files, white.png and black.png using one or the other of those light definitions.
//#declare SceneLight = rgb<1,1,1>
#declare SceneLight = rgb<0,0,0>
background { color SceneLight }
plane {
y, 0
pigment {
color SceneLight
}
}
Now the two images and extract the difference using the two background technique documented here.
magick black.png white.png -alpha off \
\( -clone 0,1 -compose difference -composite -negate \) \
\( -clone 0,2 +swap -compose divide -composite \) \
-delete 0,1 +swap -compose CopyOpacity -composite \
transparent.png
The disadvantage of this method is that you have less flexibility over scene lighting and cannot pretend to reflect anything off the ground plane. If your objects are matte enough not to be seriously affected by scene background colors then this method might be for you. It my case it saved one time consuming rendering pass and a lot of scene object manipulation.
Related
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.
I want to generate an image out of 3 images. One of these images is the background, one the shape mask and one the color of the shape.
Here are the images:
shape.png
(transparent background, white circle in the middle and black circle inside and gray circle inside the black one)
shapecolor.png
background.png
The background.png should be the overall background. On top of that is the shape and all white parts (and also the white in the gray parts) should be in the color of shapecolor.png
I used simple mono color images to make it easier but I use some textures in reality ^^
I have no idea how to solve this problem in Imagemagick, the tool is very powerful and the documentation is not so easy to understand. Tried to solve this for 3h, but did not get the result, which should look like this:
Can anyone help please?
Here is one way to do it in Imagemagick. In the second line, extract the alpha channel from omg.png and save it in an mpr: in-memory image and then delete the clone. Then I use the mpr: image later in the last step.
convert red.png img.png \
\( +clone -alpha extract -write mpr:alpha +delete \) \
-compose multiply -composite \
green.png +swap mpr:alpha -compose over -composite \
result.png
The backgroud pic:
background
The final effect:
gif effect
How do I make the red heart move and cover the background text?
I have tried this:
Convert back.png ( -clone1 -gravity center -geometry +10+10 heart.png ) (-clone 1 *******)
This just moves the heart, but did not cover the text.
How do I make the red heart move and mask part of the background text?
With mask?
Here is one way using Imagemagick. First I need to crop out the heart shape from one of your animation frames, since you did not provide that.
Heart Image:
Background Image:
First, I create a new folder on my desktop called test and put both images into it.
Here is the code in (Bash) Unix syntax.
I start backwards from the right side towards the left of the background. The i indices are then reversed using j=(55-i) for later combining in alphabetic order. The jj computation adds a leading zero to the indices less than 10 so that all frames are listed in the test folder in alphabetic order.
For each frame, it extracts the alpha channel of the background and draws a black rectangle on the right side and then puts that result back into the alpha channel of the background image using -compose copy_opacity -composite. This effectively puts transparency where the pink letters are. Then I composite the heart image as the corresponding left edge of where I had drawn the black rectangle.
After the loop finishes, I gather all the frames from the test directory with names starting with tmp_ and create a gif animation that I write to the desktop.
x=564
for ((i=0; i<56; i++)); do
j=$((55-i))
jj=`printf "%02d\n" $j`
convert background.png \
\( -clone 0 -alpha extract -fill black -draw "rectangle $x,0 639,123" \) \
-alpha off -compose copy_opacity -composite \
heartshape.png -geometry +${x}+28 -compose over -composite tmp_$jj.gif
x=$((x-8))
done
convert -dispose background -delay 10 tmp_*.gif -loop 0 ../heart_animation.gif
Note that Windows Imagemagick and scripting syntax is different. If some kind Windows user wants to post the conversion, that would be great.
I want to create a diff from two images, that can be applyed on top of first image, resulting on the same second image.
I'm trying to do like this:
convert -composite -compose difference img1.png img2.png img-diff.png
The resulting img-diff.png shows a black background where img1.png is equal to img2.png.
I want to generate the diff with a transparent background, to allow me to create an animation by combining it with the first image.
I think you need to add -transparent black before the output filename. You may, or may not, want to add a -fuzz 5% to make near black also become transparent.
So, in concrete terms, if you start off with these two images
and you then run this command:
convert 1.jpg 2.jpg -compose difference -composite -fuzz 5% -transparent black out.png
you end up with this (it shows transparent as white because SO uses JPEGs which can't show transparency).
I think the problem with your (valiant) attempt is that you need to set -compose first to tell IM how to compose the images before it actually goes ahead and does it with -composite and also you were missing the -transparent black part.
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.