Performance of ImageApply
Your If
codition is pretty simple and can be precomputed on all pixels more efficiently to generate a composition mask
mask = Binarize[ImageDifference[imageA, imageB], 0]
You can then use simple arithmetic to combine it
ImageAdd[
ImageMultiply[ColorNegate[mask], RGBColor @@ {1, 0.8, 0.2}],
ImageMultiply[mask, imageB]
]
Putting all together
fadeAndShine2[old_, new_, color: _?ColorQ : RGBColor[1, 0.8, 0.2]] :=
With[
{mask = Binarize[ImageDifference[old, new], 0]},
ImageAdd[
ImageMultiply[ColorNegate[mask], color],
ImageMultiply[mask, new]
]
]
fadeAndShine2[imageA,imageB]//AbsoluteTiming//First
(* => 0.012 *)
And
MinMax[
fadeAndShine2[imageA, imageB] -
ImageApply[fadeAndShine, {imageA, imageB}]]
(* => {0., 0.} *)
You can try to use compiled code and apply it to the ImageData
of your images:
fadeAndShine[old_, new_] := If[old == new, {1, 0.8, 0.2}, new];
cFadeAndShine = Compile[{{old, _Real, 1}, {new, _Real, 1}},
If[old == new, {1., 0.8, 0.2}, new],
CompilationTarget -> "C",
RuntimeAttributes -> {Listable},
Parallelization -> True
];
And here the usage example with timings:
imageA = Rasterize[Graphics[Table[Circle[{x, 0}, x], {x, 1, 25}]],
"Image", ImageSize -> 500];
imageB = Rasterize[Graphics[Table[Circle[{0.8 x, 0}, x], {x, 1, 25}]],
"Image", ImageSize -> 500];
imageC = ImageApply[fadeAndShine, {imageA, imageB}]; //
AbsoluteTiming // First
imageD = Image[cFadeAndShine[ImageData[imageA], ImageData[imageB]]]; //
AbsoluteTiming // First
ImageData[imageC] - ImageData[imageD] // Abs // Max
0.355039
0.035754
0.
imageA=Rasterize[Graphics[Table[Circle[{x,0},x],{x,1,25}]],"Image",ImageSize->500];
imageB=Rasterize[Graphics[Table[Circle[{0.8 x,0},x],{x,1,25}]],"Image",ImageSize->500];
data1=ImageApply[Function[{old,new},If[old==new,{1.,0.8,0.2},new]],{imageA,imageB}]//
ImageData;//AbsoluteTiming
data2=Map[With[{old=#[[{1,2,3}]],new=#[[{4,5,6}]]},If[old==new,{1.,0.8,0.2},new]]&,
Join[ImageData[imageA],ImageData[imageB],3],{2}];//AbsoluteTiming
data3=With[{old=ImageData[imageA],new=ImageData[imageB]},
With[{k=Unitize[new-old]},Map[{1.,0.8,0.2}#&, 1-k,{2}]+new k]];//AbsoluteTiming
data1==data2==data3
{0.637831, Null}
{0.249619, Null}
{0.0957136, Null}
True