
// AlphaBlend.java
// Andrew Davison, ad@coe.psu.ac.th, April 2023

/* Blend a foreground image into a background
   using changing alphas to generate a stack of 
   intermediate images. 

   Usage:
     > compile AlphaBlend.java
     > run AlphaBlend

   Based on an example from:
     Digital Image Processing – An Algorithmic Introduction 
     Wilhelm Burger and Mark J. Burge, 
     Springer, 2022, 3rd ed.
     https://imagingbook.com/
*/

import java.util.*;

import ij.*;
import ij.gui.*;
import ij.process.*;


public class AlphaBlend
{
  private static final int NUM_FRAMES = 10;


  public static void main(String[] args)
  {
    ImagePlus fgIm = new ImagePlus("ship.jpg"); // foreground image
    ImagePlus bgIm = new ImagePlus("beach.jpg"); // background

    ImageProcessor fgIp = fgIm.getProcessor().
                  convertToByte(false);  // 8-bit version; no scaling
    ImageProcessor bgIp = bgIm.getProcessor();
    ImageProcessor fgTmpIp = bgIp.duplicate();

    int w = bgIp.getWidth();
    int h = bgIp.getHeight();

    // create image stack
    ImagePlus imsStack = NewImage.createByteImage("movie", 
                                w, h, NUM_FRAMES, 0);
                                       // 0 == 'no options'
    ImageStack stack = imsStack.getStack();

    // loop over stack frames
    for (int i = 0; i < NUM_FRAMES; i++) {
      // decrease alpha (0 == transparent; 1 == opaque)
      double iAlpha = 1.0 - (double)i / (NUM_FRAMES-1);
      ImageProcessor iFrame = stack.getProcessor(i+1);

       // apply alpha; make background less visible
      iFrame.insert(bgIp, 0, 0);
      iFrame.multiply(iAlpha); 

       // apply 1-alpha; make foreground more visible 
      fgTmpIp.insert(fgIp, 0, 0);
      fgTmpIp.multiply(1 - iAlpha); 

      // add foreground to background by blitting-add
      ByteBlitter blitter = new ByteBlitter(
                                  (ByteProcessor) iFrame);
      blitter.copyBits(fgTmpIp, 0, 0, Blitter.ADD);  // x, y, blit mode
    }

    imsStack.show();

    ImageUtils.waitGone("movie");  // use stack name
    System.exit(0);
  } /* main */



}  // end of AlphaBlend class
