Skip to content

Commit 8f802b7

Browse files
committed
use only relevant icon sizes when saving files
1 parent 9c5f530 commit 8f802b7

File tree

2 files changed

+102
-44
lines changed

2 files changed

+102
-44
lines changed

IcoMerge/Form1.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ private void buttonUnpackICO_Click(object sender, EventArgs e)
5353
foreach (string file in imageFiles)
5454
{
5555
string filePrefix = Path.GetFileNameWithoutExtension(file);
56-
IconToBitmaps.LoadFiles(file, folderBrowserDialog1.SelectedPath, filePrefix, "png", radioButton2.Checked);//saveFileDialog1.FileName);
56+
IconToBitmaps.Convert(file, folderBrowserDialog1.SelectedPath, filePrefix, "png", radioButton2.Checked);//saveFileDialog1.FileName);
5757
}
5858
}
5959

IcoMerge/IconToBitmaps.cs

+101-43
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Diagnostics;
22
using System.Drawing;
33
using System.Runtime.InteropServices;
4+
using System.Security.Cryptography;
5+
using System.Security.Policy;
46

57

68
namespace IcoMerge;
@@ -9,22 +11,13 @@ namespace IcoMerge;
911
//https://gist.github.com/Willy-Kimura/d3d3541dee057c583f39005b25df65c8
1012
class IconToBitmaps
1113
{
12-
public static void UnpackPngIcon(FileStream inputStream, string outputFolder, string filePrefix, string fileExtension)
14+
public static List<IconProperties> ReadIconDirectory(int[] bytes, int numberOfIcons)
1315
{
16+
List<IconProperties> iconProperties = new List<IconProperties>();
1417

15-
long readLength = inputStream.Length;
16-
int[] bytes = new int[readLength];
17-
18-
for (int i = 0; i < readLength; i++)
19-
{
20-
int b = inputStream.ReadByte();
21-
bytes[i] = b;
22-
}
23-
int numImages = bytes[4];
24-
Debug.WriteLine("Icons in file " + numImages);
25-
26-
for (int i = 0;i < numImages;i++)
18+
for (int i = 0;i < numberOfIcons; i++)
2719
{
20+
IconProperties icon = new IconProperties();
2821
//get icon attributes
2922
int listingStart = 6 + (i * 16);
3023
int width = bytes[listingStart + 0];
@@ -33,6 +26,8 @@ public static void UnpackPngIcon(FileStream inputStream, string outputFolder, st
3326
int height = bytes[listingStart + 1];
3427
if (height == 0) { height = 256; }
3528

29+
//imageSize = Math.Max(width, height);
30+
3631
int size = bytes[listingStart+8];
3732
size += bytes[listingStart + 9]* 256;
3833
size += bytes[listingStart + 10] * 256 * 256;
@@ -41,65 +36,128 @@ public static void UnpackPngIcon(FileStream inputStream, string outputFolder, st
4136
offset += bytes[listingStart + 13] * 256;
4237
offset += bytes[listingStart + 14] * 256 * 256;
4338
offset += bytes[listingStart + 15] * 256 * 256 * 256;
44-
Debug.WriteLine($"Icon, {width}x{height}, size: {size}b, starting at byte {offset}");
39+
Debug.WriteLine($"Icon, {width}x{height}, size: {size}b, starting at byte {offset}");
40+
icon.index = i;
41+
icon.offset = offset;
42+
icon.size = size;
43+
icon.width = width;
44+
icon.height = height;
45+
iconProperties.Add( icon );
46+
}
47+
return iconProperties;
48+
}
4549

46-
//Save files
47-
string fileName = $"{filePrefix}-{i}-{width}.{fileExtension}";
48-
string filePath = Path.Combine(outputFolder, fileName);
49-
using (FileStream output_stream = new FileStream(filePath, System.IO.FileMode.OpenOrCreate))
50+
public static (int[] bytes, int numberOfIcons) ReadIconToBytes(FileStream inputStream)
51+
{
52+
long readLength = inputStream.Length;
53+
int[] bytes = new int[readLength];
54+
55+
for (int i = 0; i < readLength; i++)
56+
{
57+
int b = inputStream.ReadByte();
58+
bytes[i] = b;
59+
}
60+
int numberOfIcons = bytes[4];
61+
62+
Debug.WriteLine("Icons in file " + numberOfIcons);
63+
64+
return (bytes, numberOfIcons);
65+
}
66+
67+
public static void SaveFileFromBytes(int[] bytes, int imageSize, int index, int offset, int fileSize, string outputFolder, string filePrefix, string fileExtension)
68+
{
69+
//Save files
70+
string fileName = $"{filePrefix}-{index}-{imageSize}.{fileExtension}";
71+
string filePath = Path.Combine(outputFolder, fileName);
72+
using (FileStream output_stream = new FileStream(filePath, System.IO.FileMode.OpenOrCreate))
73+
{
74+
Debug.WriteLine($"Saving PNG-packed icon to PNG: {filePath}, size: {imageSize} from {offset} to {offset + fileSize} out of {bytes.Length} b");
75+
using (BinaryWriter bitmap_writer = new BinaryWriter(output_stream))
5076
{
51-
Debug.WriteLine($"Saving PNG-packed icon to PNG: {filePath}, size: {size} from {offset} to {offset+size} out of {bytes.Length} b");
52-
using (BinaryWriter bitmap_writer = new BinaryWriter(output_stream))
77+
for (int j = 0; j < fileSize; j++)
5378
{
54-
for (int j = 0; j < size; j++)
55-
{
56-
bitmap_writer.Write((byte)bytes[offset+j]);
57-
}
58-
bitmap_writer.Flush();
79+
bitmap_writer.Write((byte)bytes[offset + j]);
5980
}
60-
output_stream.Close();
81+
bitmap_writer.Flush();
6182
}
62-
83+
output_stream.Close();
6384
}
6485
}
6586

6687

6788

68-
public static void LoadFiles(string input_icon, string outputFolder, string filePrefix, string fileExtension, bool UnpackAsPNG)
89+
public static void Convert(string input_icon, string outputFolder, string filePrefix, string fileExtension, bool UnpackAsPNG)
6990
{
91+
FileStream input_stream = new FileStream(input_icon, System.IO.FileMode.Open);
92+
(int[] bytes, int num) = ReadIconToBytes(input_stream);
93+
List<IconProperties> iconList = ReadIconDirectory(bytes, num);// output_stream);
7094
if (UnpackAsPNG)
7195
{
72-
FileStream input_stream = new FileStream(input_icon, System.IO.FileMode.Open);
73-
UnpackPngIcon(input_stream, outputFolder, filePrefix, fileExtension);// output_stream);
96+
Debug.WriteLine("Save using PNG packed icon");
97+
foreach (IconProperties icon in iconList)
98+
{
99+
SaveFileFromBytes(bytes, icon.width, icon.index, icon.offset, icon.size, outputFolder, filePrefix, fileExtension);
100+
}
74101
input_stream.Close();
75102
}
76103
else
77104
{
78-
UnpackIcoIcon(input_icon, outputFolder, filePrefix, fileExtension);
105+
input_stream.Close();
106+
Debug.WriteLine("Save using ICO packed icon");
107+
List<int> sizes = new List<int>();
108+
foreach(IconProperties icon in iconList)
109+
{
110+
sizes.Add(icon.width);
111+
}
112+
UnpackIcoIcon(input_icon, sizes, outputFolder, filePrefix, fileExtension);
79113
}
80-
81114
}
82115

83-
public static void UnpackIcoIcon(string sourceFile, string outputFolder, string filePrefix, string fileExtension)
116+
public static void UnpackIcoIcon(string sourceFile, List<int> sizes, string outputFolder, string filePrefix, string fileExtension)
84117
{
85-
int[] sizes = { 16, 32, 24, 48, 64, 256 };
118+
Debug.Write($"Saving ICO-packed icon {sourceFile} to PNG with sizes: ");
119+
foreach (int size in sizes)
120+
{
121+
Debug.Write($"{size} ");
122+
}
123+
Debug.WriteLine("");
124+
86125
try
87126
{
88-
for (int j = 0; j < sizes.Length; j++)
89-
{
90-
Icon? icon = Icon.ExtractIcon(sourceFile, 0, sizes[j]);
91-
if (icon != null)
127+
//for (int i = 0; i < sizes.Count; i++)
128+
//{
129+
for (int j = 0; j < sizes.Count; j++)
92130
{
93-
string fileName = $"{filePrefix}-{j}-{sizes[j]}.{fileExtension}";
94-
string filePath = Path.Combine(outputFolder, fileName);
95-
Debug.WriteLine($"Saving ICO-packed icon to PNG {filePath}: {icon.Width}x{icon.Height}");
96-
icon.ToBitmap().Save(filePath);
131+
Icon? icon = Icon.ExtractIcon(sourceFile, 0, sizes[j]);
132+
//Icon icon = Icon.ExtractAssociatedIcon(sourceFile);
133+
Debug.WriteLine($"Icon {sourceFile}, size {sizes[j]}, null: {icon == null}");
134+
135+
if (icon != null)
136+
{
137+
string fileName = $"{filePrefix}-{j}-{sizes[j]}.{fileExtension}";
138+
string filePath = Path.Combine(outputFolder, fileName);
139+
Debug.WriteLine($"Saving ICO-packed icon to PNG {filePath}: {icon.Width}x{icon.Height}");
140+
icon.ToBitmap().Save(filePath);
141+
}
142+
else
143+
{
144+
Debug.WriteLine("Icon is null");
145+
}
97146
}
98-
}
147+
//}
99148
}
100149
catch (Exception ex)
101150
{
102151
Debug.WriteLine(ex.Message);
103152
}
104153
}
154+
155+
public class IconProperties
156+
{
157+
public int index;
158+
public int width;
159+
public int height;
160+
public int offset;
161+
public int size;
162+
}
105163
}

0 commit comments

Comments
 (0)