11using System ;
2- using System . Collections . Generic ;
32using System . ComponentModel ;
4- using System . Data ;
53using System . Drawing ;
64using System . Drawing . Imaging ;
75using System . IO ;
86using System . Text ;
97using System . Text . RegularExpressions ;
10- using System . Threading . Tasks ;
118using System . Windows . Forms ;
129
1310namespace Image2Bitmap
@@ -165,11 +162,13 @@ private String ImageToCode_1bpp(Image image, bool horisontal = false)
165162 else
166163 bitInBlock -- ;
167164
168- bgWork . ReportProgress ( ( int ) ( ( double ) pixelsCurrent ++ / ( double ) pixelsTotal * 100 ) ) ;
165+
169166 }
170167 }
171168 if ( ! horisontal )
172169 y += 7 ;
170+
171+ bgWork . ReportProgress ( ( int ) ( ( double ) pixelsCurrent ++ / ( double ) pixelsTotal * 100 ) ) ;
173172 }
174173 }
175174 }
@@ -208,41 +207,57 @@ private string ImageToCode(TransformColorFormats format)
208207 using ( Bitmap bmp = new Bitmap ( image , Width , Height ) )
209208 {
210209 int rowPos = 0 ;
211- Color pixelColor ;
212210
213211 int pixelsTotal = bmp . Width * bmp . Height ;
214212 int pixelsCurrent = 0 ;
215213 int ColorByte = 0 ;
214+
215+ // ===========================================================
216+ // Optimisation: Upto 5x faster than GetPixel();
217+ Rectangle rect = new Rectangle ( 0 , 0 , bmp . Width , bmp . Height ) ;
218+ System . Drawing . Imaging . BitmapData bmpData =
219+ bmp . LockBits ( rect , System . Drawing . Imaging . ImageLockMode . ReadWrite ,
220+ bmp . PixelFormat ) ;
221+
222+ IntPtr ptr = bmpData . Scan0 ;
223+ int bytes = bmpData . Stride * bmp . Height ; // ARGB: Width * Height * 4 (Stride = Width * 4)
224+ byte [ ] rgbValues = new byte [ bytes ] ;
225+
226+ // Format BGRA (GRB+Alpha, inverted). Example: BBBBBBBB GGGGGGGG RRRRRRRR AAAAAAAA
227+ System . Runtime . InteropServices . Marshal . Copy ( ptr , rgbValues , 0 , bytes ) ;
228+
229+ int pixelByte = 0 ;
230+ // ===========================================================
216231
217232 for ( int y = 0 ; y < bmp . Height ; y ++ )
218233 {
219234 for ( int x = 0 ; x < bmp . Width ; x ++ )
220235 {
221- pixelColor = bmp . GetPixel ( x , y ) ;
236+ pixelByte = ( y * bmp . Width + x ) * 4 ;
222237
223238 switch ( format )
224239 {
225240 case TransformColorFormats . RGB_332 :
226- ColorByte =
227- ( pixelColor . R & 0xE0 ) | // 0xE0 = 1110 0000
228- ( pixelColor . G & 0xE0 ) >> 3 |
229- ( pixelColor . B & 0xC0 ) >> 6 ; // 0xC0 = 1100 0000
241+ ColorByte =
242+ ( rgbValues [ pixelByte + 2 ] & 0xE0 ) | // 0xE0 = 1110 0000
243+ ( rgbValues [ pixelByte + 1 ] & 0xE0 ) >> 3 |
244+ ( rgbValues [ pixelByte + 0 ] & 0xC0 ) >> 6 ; // 0xC0 = 1100 0000
230245 break ;
231246 case TransformColorFormats . RGB_444 :
232247 // byte = 16 bit per color
233248 // RRRR RGGG GGGB BBBB
234249 ColorByte =
235- ( pixelColor . R & 0xF0 ) << 4 | // 0xF0 = 1111 0000
236- ( pixelColor . G & 0xF0 ) |
237- ( pixelColor . B & 0xF0 ) >> 4 ;
250+ ( rgbValues [ pixelByte + 2 ] & 0xF0 ) << 4 | // 0xF0 = 1111 0000
251+ ( rgbValues [ pixelByte + 1 ] & 0xF0 ) |
252+ ( rgbValues [ pixelByte + 0 ] & 0xF0 ) >> 4 ;
238253 break ;
239254 case TransformColorFormats . RGB_565 :
240255 // byte = 16 bit per color
241256 // RRRR RGGG GGGB BBBB
242257 ColorByte =
243- ( pixelColor . R & 0xF8 ) << 8 | // 0xF8 = 1111 1000
244- ( pixelColor . G & 0xFC ) << 3 | // 0xFC = 1111 1100
245- ( pixelColor . B & 0xF8 ) >> 3 ;
258+ ( rgbValues [ pixelByte + 2 ] & 0xF8 ) << 8 | // 0xF8 = 1111 1000
259+ ( rgbValues [ pixelByte + 1 ] & 0xFC ) << 3 | // 0xFC = 1111 1100
260+ ( rgbValues [ pixelByte + 0 ] & 0xF8 ) >> 3 ;
246261 break ;
247262 }
248263
@@ -255,9 +270,8 @@ private string ImageToCode(TransformColorFormats format)
255270 rowPos = 0 ;
256271 result . Append ( Environment . NewLine + "\t " ) ;
257272 }
258-
259- bgWork . ReportProgress ( ( int ) ( ( double ) pixelsCurrent / ( double ) pixelsTotal * 100 ) ) ;
260273 }
274+ bgWork . ReportProgress ( ( int ) ( ( double ) pixelsCurrent / ( double ) pixelsTotal * 100 ) ) ;
261275 }
262276 }
263277
@@ -378,6 +392,8 @@ private void CodeToImage(object sender, DoWorkEventArgs e)
378392 }
379393
380394 x ++ ;
395+ pixelsCurrent ++ ;
396+
381397 if ( x == Width )
382398 {
383399 x = 0 ;
@@ -386,17 +402,15 @@ private void CodeToImage(object sender, DoWorkEventArgs e)
386402 else
387403 y += 1 ;
388404
405+ bgWork . ReportProgress ( ( int ) ( ( double ) pixelsCurrent / ( double ) pixelsTotal * 100 ) ) ;
406+
389407 if ( y == Height )
390408 {
391409 break ; // All done. Stop conversion.
392410 }
393411 }
394- pixelsCurrent ++ ;
395-
396- bgWork . ReportProgress ( ( int ) ( ( double ) pixelsCurrent / ( double ) pixelsTotal * 100 ) ) ;
397412 }
398-
399- e . Result = result ;
413+ e . Result = result ;
400414 }
401415
402416 #endregion
@@ -465,14 +479,6 @@ private void Btn_Convert_Click(object sender, EventArgs e)
465479 bgWork . RunWorkerAsync ( selBox_Format . SelectedItem ) ;
466480 break ;
467481 }
468-
469- while ( bgWork . IsBusy )
470- {
471- convertProgress . Increment ( 1 ) ;
472- // Keep UI messages moving, so the form remains
473- // responsive during the asynchronous operation.
474- Application . DoEvents ( ) ;
475- }
476482 }
477483
478484 private void Txt_ZoomMode_LinkClicked ( object sender , LinkLabelLinkClickedEventArgs e )
0 commit comments