Skip to content

Commit 95d8cc6

Browse files
committed
Bug fix to remove transparency
Transparent pixels were causes some opaque pixels to be removed from exported frames (fixes #3). Also fix to Drag drop handler to handle null object.
1 parent ac6dd36 commit 95d8cc6

4 files changed

Lines changed: 105 additions & 33 deletions

File tree

ASU/BO/ImageUnpacker.cs

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,76 @@ public ImageUnpacker(Bitmap image, string fileName)
4646
}
4747
this.original = new Bitmap((Bitmap)image.Clone());
4848
this.originalSize = image.Size;
49+
this.original = this.RemoveTransparencyFromImage(this.original);
4950
this.boxes = new List<Rectangle>();
5051
this.FileName = fileName;
5152
this.IsLarge = (this.original.Width * this.original.Height) > (800 * 800);
5253
}
5354

55+
private Bitmap RemoveTransparencyFromImage(Bitmap image)
56+
{
57+
Dictionary<int, Color> coloursByArgb = new Dictionary<int, Color>();
58+
Dictionary<Point, Color> transparentPixelsByCoord = new Dictionary<Point, Color>();
59+
Dictionary<Color, Color> opaquedByTransparent = new Dictionary<Color, Color>();
60+
Color pixel;
61+
bool containsTransparency = false;
62+
Color transparentPixel;
63+
Color opaquedPixel;
64+
65+
for(int x = 0; x < image.Width; x++)
66+
{
67+
for(int y = 0; y < image.Height; y++)
68+
{
69+
pixel = image.GetPixel(x, y);
70+
71+
if (!coloursByArgb.ContainsKey(pixel.ToArgb()))
72+
{
73+
coloursByArgb.Add(pixel.ToArgb(), pixel);
74+
}
75+
if (pixel.A < 255)
76+
{
77+
containsTransparency = true;
78+
transparentPixelsByCoord.Add(new Point(x, y), pixel);
79+
}
80+
}
81+
}
82+
83+
if (containsTransparency)
84+
{
85+
foreach (Point coord in transparentPixelsByCoord.Keys)
86+
{
87+
transparentPixel = transparentPixelsByCoord[coord];
88+
if (opaquedByTransparent.ContainsKey(transparentPixel))
89+
{
90+
opaquedPixel = opaquedByTransparent[transparentPixel];
91+
}
92+
else
93+
{
94+
opaquedPixel = Color.FromArgb(255, transparentPixel);
95+
96+
do
97+
{
98+
if (transparentPixel.R > (255 / 2))
99+
{
100+
opaquedPixel = Color.FromArgb(opaquedPixel.R - 1, opaquedPixel.G, opaquedPixel.B);
101+
}
102+
else
103+
{
104+
opaquedPixel = Color.FromArgb(opaquedPixel.R + 1, opaquedPixel.G, opaquedPixel.B);
105+
}
106+
} while (coloursByArgb.ContainsKey(opaquedPixel.ToArgb()));
107+
108+
coloursByArgb.Remove(transparentPixel.ToArgb());
109+
coloursByArgb.Add(opaquedPixel.ToArgb(), opaquedPixel);
110+
opaquedByTransparent.Add(transparentPixel, opaquedPixel);
111+
}
112+
image.SetPixel(coord.X, coord.Y, opaquedPixel);
113+
}
114+
}
115+
116+
return image;
117+
}
118+
54119
public System.Drawing.Imaging.ColorPalette GetPallette()
55120
{
56121
return this.pallette;
@@ -330,8 +395,8 @@ private void HandleDividedArea(Rectangle region, bool updateCounter, Bitmap imag
330395

331396
private void SetBackgroundColour(Bitmap image)
332397
{
333-
Dictionary<Color, int> colours = new Dictionary<Color, int>();
334-
Color presentColour = default(Color);
398+
Dictionary<int, int> colourCountsByArgb = new Dictionary<int, int>();
399+
Color presentColour;
335400
int maxCount = 0;
336401

337402
for (int x = 0; x <= this.originalSize.Width - 1; x++)
@@ -340,13 +405,13 @@ private void SetBackgroundColour(Bitmap image)
340405
{
341406
presentColour = image.GetPixel(x, y);
342407

343-
if (!colours.ContainsKey(presentColour))
408+
if (!colourCountsByArgb.ContainsKey(presentColour.ToArgb()))
344409
{
345-
colours.Add(presentColour, 1);
410+
colourCountsByArgb.Add(presentColour.ToArgb(), 1);
346411
}
347412
else
348413
{
349-
colours[presentColour] += 1;
414+
colourCountsByArgb[presentColour.ToArgb()] += 1;
350415
}
351416

352417
if ((x + y) % 100 == 0)
@@ -359,17 +424,17 @@ private void SetBackgroundColour(Bitmap image)
359424
}
360425
}
361426

362-
foreach (Color colour in colours.Keys)
427+
foreach (int colourArgb in colourCountsByArgb.Keys)
363428
{
364-
if (colours[colour] >= maxCount)
429+
if (colourCountsByArgb[colourArgb] >= maxCount)
365430
{
366-
maxCount = colours[colour];
367-
this.backgroundColour = colour;
431+
maxCount = colourCountsByArgb[colourArgb];
432+
this.backgroundColour = Color.FromArgb(colourArgb);
368433
}
369434
}
370435
image.Dispose();
371436
this._isBackgroundColourSet = true;
372-
this.ColoursCount = colours.Count - 1;
437+
this.ColoursCount = colourCountsByArgb.Count - 1;
373438
}
374439

375440
private void HandleUnpackComplete()

ASU/BO/RegionUnpacker.cs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,26 +57,26 @@ private static List<Rectangle> CreateBoxes(Bitmap image, Rectangle region, Color
5757

5858
presentColour = image.GetPixel(x, y);
5959

60-
if (presentColour != background)
60+
if (presentColour.ToArgb() != background.ToArgb())
6161
{
6262
newBox = new Rectangle(presentPixel, new Size(0, 0));
6363
x2 = x;
6464

65-
while (x2 < (image.Width - 1) && image.GetPixel(x2, y) != background)
65+
while (x2 < (image.Width - 1) && image.GetPixel(x2, y).ToArgb() != background.ToArgb())
6666
{
6767
x2 += 1;
6868
newBox = new Rectangle(newBox.X, newBox.Y, newBox.Width + 1, newBox.Height);
6969
}
7070

7171
y2 = y;
72-
while (y2 < (image.Height - 1) && image.GetPixel(x2, y2) != background)
72+
while (y2 < (image.Height - 1) && image.GetPixel(x2, y2).ToArgb() != background.ToArgb())
7373
{
7474
y2 += 1;
7575
newBox = new Rectangle(newBox.X, newBox.Y, newBox.Width, newBox.Height + 1);
7676
}
7777

7878
y2 = y + newBox.Height;
79-
while (y2 < (image.Height - 1) && image.GetPixel(x, y2) != background)
79+
while (y2 < (image.Height - 1) && image.GetPixel(x, y2).ToArgb() != background.ToArgb())
8080
{
8181
y2 += 1;
8282
newBox = new Rectangle(newBox.X, newBox.Y, newBox.Width, newBox.Height + 1);
@@ -204,8 +204,8 @@ private static bool DoBoxesContainAdjacentOrOverlappingPixels(Rectangle box1, Re
204204
for (int x = intersection.X; x <= intersection.Right; x++)
205205
{
206206
for (int y = intersection.Y; y <= intersection.Bottom; y++)
207-
{
208-
if (image.GetPixel(x, y) != background)
207+
{
208+
if (image.GetPixel(x, y).ToArgb() != background.ToArgb())
209209
{
210210
return true;
211211
}
@@ -214,29 +214,27 @@ private static bool DoBoxesContainAdjacentOrOverlappingPixels(Rectangle box1, Re
214214

215215
}
216216

217-
218217
if (ForkandBeard.Util.Geometry.GeometryHelper.GetXGapBetweenRectangles(box1, box2) <= UI.MainForm.DistanceBetweenTiles)
219218
{
220219
for (int y = box1.Y - UI.MainForm.DistanceBetweenTiles; y <= box1.Bottom + UI.MainForm.DistanceBetweenTiles; y++)
221220
{
222-
223221
if (y >= box2.Top && y <= box2.Bottom)
224222
{
225223
if (box2.Left > box1.Right)
226224
{
227-
if (image.GetPixel(box1.Right, y) != background)
225+
if (image.GetPixel(box1.Right, y).ToArgb() != background.ToArgb())
228226
{
229-
if (image.GetPixel(box2.Left, y) != background)
227+
if (image.GetPixel(box2.Left, y).ToArgb() != background.ToArgb())
230228
{
231229
return true;
232230
}
233231
}
234232
}
235233
else
236234
{
237-
if (image.GetPixel(box1.Left, y) != background)
235+
if (image.GetPixel(box1.Left, y).ToArgb() != background.ToArgb())
238236
{
239-
if (image.GetPixel(box2.Right, y) != background)
237+
if (image.GetPixel(box2.Right, y).ToArgb() != background.ToArgb())
240238
{
241239
return true;
242240
}
@@ -247,29 +245,27 @@ private static bool DoBoxesContainAdjacentOrOverlappingPixels(Rectangle box1, Re
247245
}
248246
}
249247

250-
251248
if (ForkandBeard.Util.Geometry.GeometryHelper.GetYGapBetweenRectangles(box1, box2) <= UI.MainForm.DistanceBetweenTiles)
252249
{
253250
for (int x = box1.Left - UI.MainForm.DistanceBetweenTiles; x <= box1.Right + UI.MainForm.DistanceBetweenTiles; x++)
254251
{
255-
256252
if (x >= box2.Left && x <= box2.Right)
257253
{
258254
if (box2.Top > box1.Bottom)
259255
{
260-
if (image.GetPixel(x, box1.Bottom) != background)
256+
if (image.GetPixel(x, box1.Bottom).ToArgb() != background.ToArgb())
261257
{
262-
if (image.GetPixel(x, box2.Top) != background)
258+
if (image.GetPixel(x, box2.Top).ToArgb() != background.ToArgb())
263259
{
264260
return true;
265261
}
266262
}
267263
}
268264
else
269265
{
270-
if (image.GetPixel(x, box1.Top) != background)
266+
if (image.GetPixel(x, box1.Top).ToArgb() != background.ToArgb())
271267
{
272-
if (image.GetPixel(x, box2.Bottom) != background)
268+
if (image.GetPixel(x, box2.Bottom).ToArgb() != background.ToArgb())
273269
{
274270
return true;
275271
}

ASU/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("14.0.0.0")]
36-
[assembly: AssemblyFileVersion("14.0.0.0")]
35+
[assembly: AssemblyVersion("15.0.0.0")]
36+
[assembly: AssemblyFileVersion("15.0.0.0")]

ASU/UI/MainForm.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,10 @@ private void MainPanel_DragDrop(object sender, System.Windows.Forms.DragEventArg
437437
{
438438
dropped = e.Data.GetData(objFormat);
439439

440-
if (object.ReferenceEquals(dropped.GetType(), typeof(string[])))
440+
if(
441+
(dropped != null)
442+
&& (object.ReferenceEquals(dropped.GetType(), typeof(string[])))
443+
)
441444
{ // Dropped object is an array of string, so assume they are file names.
442445
Bitmap image;
443446
List<string> fileNames = null;
@@ -909,6 +912,7 @@ private void ExportUnpackers(List<BO.ImageUnpacker> unpackers)
909912
bool userOkToConvertFiles = true;
910913
List<Rectangle> boxes = null;
911914
DateTime lapse = System.DateTime.MinValue;
915+
System.Windows.Forms.DialogResult folderResponse = System.Windows.Forms.DialogResult.Cancel;
912916

913917
try
914918
{
@@ -919,10 +923,17 @@ private void ExportUnpackers(List<BO.ImageUnpacker> unpackers)
919923

920924
if (this.Selected.Count > 0 || unpackers.Count > 1)
921925
{
922-
foreach (BO.ImageUnpacker unpacker in unpackers)
926+
if (PromptForDestinationFolder)
923927
{
928+
folderResponse = this.FolderBrowserDialog1.ShowDialog();
929+
}
924930

925-
if ((PromptForDestinationFolder && this.FolderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) || !PromptForDestinationFolder)
931+
foreach (BO.ImageUnpacker unpacker in unpackers)
932+
{
933+
if (
934+
(folderResponse == System.Windows.Forms.DialogResult.OK)
935+
|| (!PromptForDestinationFolder)
936+
)
926937
{
927938
if (PromptForDestinationFolder)
928939
{

0 commit comments

Comments
 (0)