@@ -81,6 +81,72 @@ function ditherHalftone(mono, w, h) {
8181 return mono ;
8282}
8383
84+ // Looked at https://github.com/Lana-chan/webgbcam for the
85+ // Bayer/ordered dithering function.
86+ function ditherBayer ( mono , w , h ) {
87+ const bayer8 = [
88+ 0 , 48 , 12 , 60 , 3 , 51 , 15 , 63 ,
89+ 32 , 16 , 44 , 28 , 35 , 19 , 47 , 31 ,
90+ 8 , 56 , 4 , 52 , 11 , 59 , 7 , 55 ,
91+ 40 , 24 , 36 , 20 , 43 , 27 , 39 , 23 ,
92+ 2 , 50 , 14 , 62 , 1 , 49 , 13 , 61 ,
93+ 34 , 18 , 46 , 30 , 33 , 17 , 45 , 29 ,
94+ 10 , 58 , 6 , 54 , 9 , 57 , 5 , 53 ,
95+ 42 , 26 , 38 , 22 , 41 , 25 , 37 , 21
96+ ] ;
97+
98+ const ditherFactor = 0.6 ; // Same as webgbcam default
99+ let p = 0 ;
100+
101+ for ( let j = 0 ; j < h ; ++ j ) {
102+ for ( let i = 0 ; i < w ; ++ i ) {
103+ let bayerValue = bayer8 [ ( j % 8 ) * 8 + ( i % 8 ) ] ;
104+
105+ let pixelValue = mono [ p ] ;
106+ pixelValue = pixelValue + ( ( bayerValue - 32 ) * ditherFactor ) ;
107+
108+ if ( pixelValue < 0 ) pixelValue = 0 ;
109+ if ( pixelValue > 255 ) pixelValue = 255 ;
110+
111+ mono [ p ] = pixelValue > 128 ? 0xff : 0x00 ;
112+ ++ p ;
113+ }
114+ }
115+ return mono ;
116+ }
117+
118+ // Thanks Bill! https://beyondloom.com/blog/dither.html
119+ function ditherAtkinson ( mono , w , h ) {
120+ let p = 0 ;
121+ let oldPixel , newPixel , error ;
122+
123+ for ( let j = 0 ; j < h ; ++ j ) {
124+ for ( let i = 0 ; i < w ; ++ i ) {
125+ oldPixel = mono [ p ] ;
126+ newPixel = oldPixel > 0x80 ? 0xff : 0x00 ;
127+ error = ( oldPixel - newPixel ) >> 3 ; // Divide by 8
128+ mono [ p ] = newPixel ;
129+
130+ if ( i < w - 1 )
131+ mono [ p + 1 ] += error ;
132+ if ( i < w - 2 )
133+ mono [ p + 2 ] += error ;
134+ if ( j < h - 1 ) {
135+ if ( i > 0 )
136+ mono [ p + w - 1 ] += error ;
137+ mono [ p + w ] += error ;
138+ if ( i < w - 1 )
139+ mono [ p + w + 1 ] += error ;
140+ }
141+ if ( j < h - 2 )
142+ mono [ p + 2 * w ] += error ;
143+
144+ ++ p ;
145+ }
146+ }
147+ return mono ;
148+ }
149+
84150function rotate ( before , w , h , turn ) {
85151 const after = new Uint8Array ( before . length ) ;
86152 switch ( turn ) {
@@ -147,9 +213,15 @@ self.addEventListener('message', function(event) {
147213 const w = msg . width , h = msg . height ;
148214 let mono = rgbaToGray ( input , msg . brightness , true ) ;
149215 switch ( msg . dither ) {
150- case 'pic ' :
216+ case 'steinberg ' :
151217 mono = ditherSteinberg ( mono , w , h ) ;
152218 break ;
219+ case 'bayer' :
220+ mono = ditherBayer ( mono , w , h ) ;
221+ break ;
222+ case 'atkinson' :
223+ mono = ditherAtkinson ( mono , w , h ) ;
224+ break ;
153225 case 'pattern' :
154226 mono = ditherHalftone ( mono , w , h ) ;
155227 break ;
0 commit comments