stack-o-frankie
stack-o-frankie

Reputation: 457

merge a png with transparency onto another image

I'm trying to merge a png with some transparency on a background:

 Mat frg = Highgui.imread( "path/to/foreground/image.png" ), -1 );    
 Mat bkg = Highgui.imread( "path/to/background/image.png" ), -1 );

 // Create mask from foreground.
 Mat mask = new Mat( frg.width(), frg.height(), 24 );
 double f[] = { 1, 1, 1, 0 };
 double e[] = { 0, 0, 0, 0 };

 for ( int y = 0; y < ( int )( frg.rows() ); ++y ) {
   for ( int x = 0; x < ( int )( frg.cols() ); ++x ) {     
     double info[] = frg.get( y, x );                 

     if ( info[3] > 0 ) {
       mask.put( y, x, e );
     } else {
       mask.put( y, x, f );
     }
   }
 } 

 // Copy foreground onto background using mask.
 frg.copyTo( bkg, mask );

 Highgui.imwrite( "path/to/result/image.png", bkg );

The resulting image is a kind of ghost showing the background image repeated various times and the foreground one in a corrupted way.

Any clues?

Upvotes: 2

Views: 1738

Answers (1)

stack-o-frankie
stack-o-frankie

Reputation: 457

Thanks Rosa and for those interested, here is how I translated into Java the C++ snippet pointed out by Rosa:

private Mat overtrayImage( Mat background, Mat foreground ) {
  // The background and the foreground are assumed to be of the same size.
  Mat destination = new Mat( background.size(), background.type() );

  for ( int y = 0; y < ( int )( background.rows() ); ++y ) {
    for ( int x = 0; x < ( int )( background.cols() ); ++x ) {     
      double b[] = background.get( y, x );
      double f[] = foreground.get( y, x );

      double alpha = f[3] / 255.0;

      double d[] = new double[3];
      for ( int k = 0; k < 3; ++k ) {
        d[k] = f[k] * alpha + b[k] * ( 1.0 - alpha );
      }

      destination.put( y, x, d );
    }
  } 

  return destination;
}

Upvotes: 1

Related Questions