# Combine two Image3D objects given a mask

Assume that we have:

Dimensions @ arr (* 128, 128, 128 *)

imgAlpha = Image3D[arr, ColorFunction -> "GrayLevelOpacity"]
imgBeta = Image3D[arr, ColorFunction -> "RainbowOpacity"]


Furthermore, we have a binary mask arrMask that has the same dimensions as arr (i.e. 128x128x128).

How can I create an Image3D whose colors are equal to imgAlpha whenever arrMask = 1 and equal to imgBeta if not?

Overlay[{imgAlpha, imgBeta}] kind of works but it produces a (2D) Image (and doesn't use a mask).

Here's a very manual way to tackle this. First I'll generate an array and mask for this purpose. Doesn't really matter what I choose, but good for reproducibility.

arr = ImageData@
RegionImage[
KnotData["Trefoil", "Region"],
3.2*{{-1, 1}, {-1, 1}, {-1, 1}},
RasterSize -> 128
];
RegionImage[
Ball[{0, 0, 0}, 1.5],
3.2*{{-1, 1}, {-1, 1}, {-1, 1}},
RasterSize -> 128
];


Next I use the trick here to get the actual color functions that you're interested in

rainbowOpacityColorFunc =
(Blend[{{0., RGBColor[0.471412, 0.108766, 0.527016, 0.]}, {0.333333,
RGBColor[0.324106, 0.60897, 0.708341, 0.333333]}, {0.666667,
RGBColor[0.764712, 0.728302, 0.273608, 0.666667]}, {1.,
RGBColor[0.857359, 0.131106, 0.132128, 1.]}}, #1] & );
grayLevelOpacityColorFunc =
(Blend[{{0., RGBColor[0., 0., 0., 0.]}, {1.,
RGBColor[1., 1., 1., 1.]}}, #1] & );


finally I use those to convert the masked image and its complement to the appropriate 4-channel versions

alphaData =
(1 - mask)*DeveloperToPackedArray@Map[
Apply[List]@*rainbowOpacityColorFunc,
{3}
];
Apply[List]@*grayLevelOpacityColorFunc,

alphaImage = Image3D[alphaData, ColorSpace -> "RGB"]