@@ -71,7 +71,7 @@ export default function pixelmatch(img1, img2, output, width, height, options =
7171 const x = i % width ;
7272 const y = ( i / width ) | 0 ;
7373 // check it's a real rendering difference or just anti-aliasing
74- const isExcludedAA = ! includeAA && ( antialiased ( img1 , x , y , width , height , a32 , b32 , checkerboard ) || antialiased ( img2 , x , y , width , height , b32 , a32 , checkerboard ) ) ;
74+ const isExcludedAA = ! includeAA && ( antialiased ( img1 , x , y , width , height , a32 , b32 ) || antialiased ( img2 , x , y , width , height , b32 , a32 ) ) ;
7575 if ( isExcludedAA ) {
7676 // one of the pixels is anti-aliasing; draw as yellow and do not count as difference
7777 // note that we do not include such pixels in a mask
@@ -115,9 +115,8 @@ function isPixelData(arr) {
115115 * @param {number } height
116116 * @param {Uint32Array } a32
117117 * @param {Uint32Array } b32
118- * @param {boolean } checkerboard
119118 */
120- function antialiased ( img , x1 , y1 , width , height , a32 , b32 , checkerboard ) {
119+ function antialiased ( img , x1 , y1 , width , height , a32 , b32 ) {
121120 const x0 = x1 > 0 ? x1 - 1 : 0 ;
122121 const y0 = y1 > 0 ? y1 - 1 : 0 ;
123122 const x2 = x1 < width - 1 ? x1 + 1 : width - 1 ;
@@ -144,7 +143,7 @@ function antialiased(img, x1, y1, width, height, a32, b32, checkerboard) {
144143 if ( x === x1 && y === y1 ) continue ;
145144
146145 // brightness delta between the center pixel and adjacent one
147- const delta = brightnessDelta ( img , pos4 , m , cr , cg , cb , ca , checkerboard ) ;
146+ const delta = brightnessDelta ( img , m , cr , cg , cb , ca ) ;
148147
149148 // count the number of equal, darker and brighter adjacent pixels
150149 if ( delta === 0 ) {
@@ -451,16 +450,20 @@ function toe(L) {
451450 * the detector only needs a cheap, monotonic scalar to find the intensity ramp direction
452451 * (darkest/brightest neighbor), and switching to ΔL both regressed AA detection on dark regions
453452 * and was much slower (called up to 16× per candidate pixel).
453+ *
454+ * Semi-transparent pixels are composited over fixed mid-gray rather than the checkerboard
455+ * used by `colorDelta`: a ramp structure test needs a deterministic background, and a
456+ * pseudo-random per-position one distorts the very ramps it looks for. When the composited
457+ * luma delta cancels out exactly but alpha differs, the alpha delta gives the ramp direction,
458+ * so only pixels equal in both premultiplied luma and alpha count as equal siblings.
454459 * @param {Uint8Array | Uint8ClampedArray } img
455- * @param {number } k center pixel offset
456460 * @param {number } m neighbor pixel offset
457461 * @param {number } r1
458462 * @param {number } g1
459463 * @param {number } b1
460464 * @param {number } a1
461- * @param {boolean } checkerboard
462465 */
463- function brightnessDelta ( img , k , m , r1 , g1 , b1 , a1 , checkerboard ) {
466+ function brightnessDelta ( img , m , r1 , g1 , b1 , a1 ) {
464467 const r2 = img [ m ] ;
465468 const g2 = img [ m + 1 ] ;
466469 const b2 = img [ m + 2 ] ;
@@ -474,15 +477,11 @@ function brightnessDelta(img, k, m, r1, g1, b1, a1, checkerboard) {
474477 if ( ! dr && ! dg && ! db && ! da ) return 0 ;
475478
476479 if ( a1 < 255 || a2 < 255 ) {
477- let rb = 255 , gb = 255 , bb = 255 ;
478- if ( checkerboard ) {
479- rb = 48 + 159 * ( k % 2 ) ;
480- gb = 48 + 159 * ( ( k / 1.618033988749895 | 0 ) % 2 ) ;
481- bb = 48 + 159 * ( ( k / 2.618033988749895 | 0 ) % 2 ) ;
482- }
483- dr = ( r1 * a1 - r2 * a2 - rb * da ) / 255 ;
484- dg = ( g1 * a1 - g2 * a2 - gb * da ) / 255 ;
485- db = ( b1 * a1 - b2 * a2 - bb * da ) / 255 ;
480+ dr = ( r1 * a1 - r2 * a2 - 128 * da ) / 255 ;
481+ dg = ( g1 * a1 - g2 * a2 - 128 * da ) / 255 ;
482+ db = ( b1 * a1 - b2 * a2 - 128 * da ) / 255 ;
483+ const d = dr * 0.29889531 + dg * 0.58662247 + db * 0.11448223 ;
484+ return d === 0 && da ? da / 2 : d ;
486485 }
487486
488487 return dr * 0.29889531 + dg * 0.58662247 + db * 0.11448223 ;
0 commit comments