Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d5ca1dd

Browse files
committed
all tested and working
revised formula for in/out/dest-in/dest-out, for vector and scalar paths see libvips#1301
1 parent 447e0f3 commit d5ca1dd

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

libvips/conversion/composite.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* - don't stop on first non-transparent image [felixbuenemann, GDmac]
1414
* 6/12/18
1515
* - do our own subimage positioning
16+
* 8/5/19
17+
* - revise in/out/dest-in/dest-out to make smoother alpha
1618
*/
1719

1820
/*
@@ -461,14 +463,18 @@ vips_composite_base_blend( VipsCompositeBase *composite,
461463

462464
case VIPS_BLEND_MODE_IN:
463465
aR = aA * aB;
464-
for( int b = 0; b < bands; b++ )
465-
B[b] = A[b];
466+
// if aA == 0, then aR == 0 and so B will already be 0
467+
if( aA != 0 )
468+
for( int b = 0; b < bands; b++ )
469+
B[b] = A[b] * aR / aA;
466470
break;
467471

468472
case VIPS_BLEND_MODE_OUT:
469473
aR = aA * (1 - aB);
470-
for( int b = 0; b < bands; b++ )
471-
B[b] = A[b];
474+
// if aA == 0, then aR == 0 and so B will already be 0
475+
if( aA != 0 )
476+
for( int b = 0; b < bands; b++ )
477+
B[b] = A[b] * aR / aA;
472478
break;
473479

474480
case VIPS_BLEND_MODE_ATOP:
@@ -493,11 +499,18 @@ vips_composite_base_blend( VipsCompositeBase *composite,
493499
case VIPS_BLEND_MODE_DEST_IN:
494500
aR = aA * aB;
495501
// B = B
502+
if( aB != 0 )
503+
for( int b = 0; b < bands; b++ )
504+
B[b] *= aR / aB;
496505
break;
497506

498507
case VIPS_BLEND_MODE_DEST_OUT:
499508
aR = (1 - aA) * aB;
500509
// B = B
510+
// if aB is 0, then B is already 0
511+
if( aB != 0 )
512+
for( int b = 0; b < bands; b++ )
513+
B[b] *= aR / aB;
501514
break;
502515

503516
case VIPS_BLEND_MODE_DEST_ATOP:
@@ -676,8 +689,8 @@ vips_composite_base_blend3( VipsCompositeBase *composite,
676689
/* See https://www.cairographics.org/operators for a nice summary of
677690
* the operators and their meaning.
678691
*
679-
* Some operators need the unpremultiplied values, so we have to do an
680-
* extra unpremultiply/premultiply.
692+
* Some operators need the unpremultiplied values (eg. dest-in), so
693+
* we have to do an extra unpremultiply/premultiply.
681694
*/
682695

683696
switch( mode ) {
@@ -701,18 +714,14 @@ vips_composite_base_blend3( VipsCompositeBase *composite,
701714

702715
case VIPS_BLEND_MODE_IN:
703716
aR = aA * aB;
704-
// we want to set B = A, but A has been premultiplied against
705-
// aA ... we must undo that premul and redo against aR
706-
// if aA == 0, then aR == 0 and so B will be set to 0
717+
// if aA == 0, then aR == 0 and so B will already be 0
707718
if( aA != 0 )
708719
B = A * aR / aA;
709720
break;
710721

711722
case VIPS_BLEND_MODE_OUT:
712723
aR = aA * (1 - aB);
713-
// we want to set B = A, but A has been premultiplied against
714-
// aA ... we must undo that premul and redo against aR
715-
// if aA == 0, then aR == 0 and so B will be set to 0
724+
// if aA == 0, then aR == 0 and so B will already be 0
716725
if( aA != 0 )
717726
B = A * aR / aA;
718727
break;
@@ -736,17 +745,17 @@ vips_composite_base_blend3( VipsCompositeBase *composite,
736745

737746
case VIPS_BLEND_MODE_DEST_IN:
738747
aR = aA * aB;
739-
// we need to simply copy B over, but B is premultiplied
740-
// against aB ... we must unpremultiply and premultiply
741-
// against aR instead
742-
// if aB is 0, then B is 0 too
743-
//if( aB != 0 )
744-
//B *= aR / aB;
748+
// if aB is 0, then B is already 0
749+
if( aB != 0 )
750+
B *= aR / aB;
745751
break;
746752

747753
case VIPS_BLEND_MODE_DEST_OUT:
748754
aR = (1 - aA) * aB;
749755
// B = B
756+
// if aB is 0, then B is already 0
757+
if( aB != 0 )
758+
B *= aR / aB;
750759
break;
751760

752761
case VIPS_BLEND_MODE_DEST_ATOP:

0 commit comments

Comments
 (0)