Skip to content
This repository was archived by the owner on May 12, 2022. It is now read-only.

Commit 2136245

Browse files
committed
Fixed form freeze
RGB-332/444/565 Image-to-code algorithm optimisation (Upto 5x faster)
1 parent 71dea14 commit 2136245

4 files changed

Lines changed: 59 additions & 46 deletions

File tree

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
*~
22
*.[oa]
3-
/.vs
3+
*.psess
4+
*.vsp
5+
*.vs
46
/Debug
57
/*/__vm
68
/*/Debug

Image2Bitmap.sln

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26730.16
4+
VisualStudioVersion = 15.0.27004.2005
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Image2Bitmap", "Image2Bitmap\Image2Bitmap.csproj", "{9F9C6B42-B7CB-4175-9DED-7EB94D3B617F}"
77
EndProject
88
Global
9+
GlobalSection(Performance) = preSolution
10+
HasPerformanceSessions = true
11+
EndGlobalSection
912
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1013
Debug|Any CPU = Debug|Any CPU
1114
Release|Any CPU = Release|Any CPU

Image2Bitmap/Form1.Designer.cs

Lines changed: 15 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Image2Bitmap/Form1.cs

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.ComponentModel;
4-
using System.Data;
53
using System.Drawing;
64
using System.Drawing.Imaging;
75
using System.IO;
86
using System.Text;
97
using System.Text.RegularExpressions;
10-
using System.Threading.Tasks;
118
using System.Windows.Forms;
129

1310
namespace 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

Comments
 (0)