@@ -496,37 +496,40 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
496
496
out_alpha *= _resample (self , alpha , out_shape , t , resample = True )
497
497
# mask and run through the norm
498
498
resampled_masked = np .ma .masked_array (A_resampled , out_mask )
499
- output = self .norm (resampled_masked )
499
+ res = self .norm (resampled_masked )
500
500
else :
501
501
if A .ndim == 2 : # interpolation_stage = 'rgba'
502
502
self .norm .autoscale_None (A )
503
503
A = self .to_rgba (A )
504
+ if A .dtype == np .uint8 :
505
+ # uint8 is too imprecise for premultiplied alpha roundtrips.
506
+ A = np .divide (A , 0xff , dtype = np .float32 )
504
507
alpha = self .get_alpha ()
508
+ post_apply_alpha = False
505
509
if alpha is None : # alpha parameter not specified
506
510
if A .shape [2 ] == 3 : # image has no alpha channel
507
- output_alpha = 255 if A .dtype == np .uint8 else 1.0
508
- else :
509
- output_alpha = _resample ( # resample alpha channel
510
- self , A [..., 3 ], out_shape , t )
511
- output = _resample ( # resample rgb channels
512
- self , _rgb_to_rgba (A [..., :3 ]), out_shape , t )
511
+ A = np .dstack ([A , np .ones (A .shape [:2 ])])
513
512
elif np .ndim (alpha ) > 0 : # Array alpha
514
513
# user-specified array alpha overrides the existing alpha channel
515
- output_alpha = _resample (self , alpha , out_shape , t )
516
- output = _resample (
517
- self , _rgb_to_rgba (A [..., :3 ]), out_shape , t )
514
+ A = np .dstack ([A [..., :3 ], alpha ])
518
515
else : # Scalar alpha
519
516
if A .shape [2 ] == 3 : # broadcast scalar alpha
520
- output_alpha = ( 255 * alpha ) if A . dtype == np .uint8 else alpha
517
+ A = np . dstack ([ A , np . full ( A . shape [: 2 ], alpha , np .float32 )])
521
518
else : # or apply scalar alpha to existing alpha channel
522
- output_alpha = _resample (self , A [..., 3 ], out_shape , t ) * alpha
523
- output = _resample (
524
- self , _rgb_to_rgba (A [..., :3 ]), out_shape , t )
525
- output [..., 3 ] = output_alpha # recombine rgb and alpha
526
-
527
- # output is now either a 2D array of normed (int or float) data
519
+ post_apply_alpha = True
520
+ # Resample in premultiplied alpha space. (TODO: Consider
521
+ # implementing premultiplied-space resampling in
522
+ # span_image_resample_rgba_affine::generate?)
523
+ A [..., :3 ] *= A [..., 3 :]
524
+ res = _resample (self , A , out_shape , t )
525
+ np .divide (res [..., :3 ], res [..., 3 :], out = res [..., :3 ],
526
+ where = res [..., 3 :] != 0 )
527
+ if post_apply_alpha :
528
+ res [..., 3 ] *= alpha
529
+
530
+ # res is now either a 2D array of normed (int or float) data
528
531
# or an RGBA array of re-sampled input
529
- output = self .to_rgba (output , bytes = True , norm = False )
532
+ output = self .to_rgba (res , bytes = True , norm = False )
530
533
# output is now a correctly sized RGBA array of uint8
531
534
532
535
# Apply alpha *after* if the input was greyscale without a mask
0 commit comments