@@ -270,15 +270,31 @@ macro_rules! median_channel {
270
270
if $top. next. a > 0 { $top. next. $chan } else { $mid. curr. $chan } ,
271
271
if $mid. prev. a > 0 { $mid. prev. $chan } else { $mid. curr. $chan } ,
272
272
$mid. curr. $chan, // if the center pixel is transparent, the result won't be used
273
- $mid. curr. $chan, // more weight on the center
274
273
if $mid. next. a > 0 { $mid. next. $chan } else { $mid. curr. $chan } ,
275
274
if $bot. prev. a > 0 { $bot. prev. $chan } else { $mid. curr. $chan } ,
276
275
if $bot. curr. a > 0 { $bot. curr. $chan } else { $mid. curr. $chan } ,
277
276
if $bot. next. a > 0 { $bot. next. $chan } else { $mid. curr. $chan } ,
278
- ] . select_nth_unstable( 5 ) . 1
277
+ ] . select_nth_unstable( 4 ) . 1
279
278
}
280
279
}
281
280
281
+ /// Average of 9 neighboring pixels
282
+ macro_rules! blur_channel {
283
+ ( $top: expr, $mid: expr, $bot: expr, $chan: ident) => { {
284
+ let mut tmp = 0u16 ;
285
+ tmp += u16 :: from( if $top. prev. a > 0 { $top. prev. $chan } else { $mid. curr. $chan } ) ;
286
+ tmp += u16 :: from( if $top. curr. a > 0 { $top. curr. $chan } else { $mid. curr. $chan } ) ;
287
+ tmp += u16 :: from( if $top. next. a > 0 { $top. next. $chan } else { $mid. curr. $chan } ) ;
288
+ tmp += u16 :: from( if $mid. prev. a > 0 { $mid. prev. $chan } else { $mid. curr. $chan } ) ;
289
+ tmp += u16 :: from( $mid. curr. $chan) ; // if the center pixel is transparent, the result won't be used
290
+ tmp += u16 :: from( if $mid. next. a > 0 { $mid. next. $chan } else { $mid. curr. $chan } ) ;
291
+ tmp += u16 :: from( if $bot. prev. a > 0 { $bot. prev. $chan } else { $mid. curr. $chan } ) ;
292
+ tmp += u16 :: from( if $bot. curr. a > 0 { $bot. curr. $chan } else { $mid. curr. $chan } ) ;
293
+ tmp += u16 :: from( if $bot. next. a > 0 { $bot. next. $chan } else { $mid. curr. $chan } ) ;
294
+ ( tmp / 9 ) as u8
295
+ } }
296
+ }
297
+
282
298
pub ( crate ) fn smart_blur ( frame : ImgRef < RGBA8 > ) -> ImgVec < RGB8 > {
283
299
let mut out = Vec :: with_capacity ( frame. width ( ) * frame. height ( ) ) ;
284
300
loop9_img ( frame, |_, _, top, mid, bot| {
@@ -288,7 +304,25 @@ pub(crate) fn smart_blur(frame: ImgRef<RGBA8>) -> ImgVec<RGB8> {
288
304
let median_b = median_channel ! ( top, mid, bot, b) ;
289
305
290
306
let blurred = RGB8 :: new ( median_r, median_g, median_b) ;
291
- // diff limit, because median removes thin lines too
307
+ if color_diff ( mid. curr . rgb ( ) , blurred) < 16 * 16 * 6 {
308
+ blurred
309
+ } else {
310
+ mid. curr . rgb ( )
311
+ }
312
+ } else { RGB8 :: new ( 255 , 0 , 255 ) } ) ;
313
+ } ) ;
314
+ ImgVec :: new ( out, frame. width ( ) , frame. height ( ) )
315
+ }
316
+
317
+ pub ( crate ) fn less_smart_blur ( frame : ImgRef < RGBA8 > ) -> ImgVec < RGB8 > {
318
+ let mut out = Vec :: with_capacity ( frame. width ( ) * frame. height ( ) ) ;
319
+ loop9_img ( frame, |_, _, top, mid, bot| {
320
+ out. push_in_cap ( if mid. curr . a > 0 {
321
+ let median_r = blur_channel ! ( top, mid, bot, r) ;
322
+ let median_g = blur_channel ! ( top, mid, bot, g) ;
323
+ let median_b = blur_channel ! ( top, mid, bot, b) ;
324
+
325
+ let blurred = RGB8 :: new ( median_r, median_g, median_b) ;
292
326
if color_diff ( mid. curr . rgb ( ) , blurred) < 16 * 16 * 6 {
293
327
blurred
294
328
} else {
0 commit comments