1
1
using System . Diagnostics ;
2
2
using System . Drawing ;
3
3
using System . Runtime . InteropServices ;
4
+ using System . Security . Cryptography ;
5
+ using System . Security . Policy ;
4
6
5
7
6
8
namespace IcoMerge ;
@@ -9,22 +11,13 @@ namespace IcoMerge;
9
11
//https://gist.github.com/Willy-Kimura/d3d3541dee057c583f39005b25df65c8
10
12
class IconToBitmaps
11
13
{
12
- public static void UnpackPngIcon ( FileStream inputStream , string outputFolder , string filePrefix , string fileExtension )
14
+ public static List < IconProperties > ReadIconDirectory ( int [ ] bytes , int numberOfIcons )
13
15
{
16
+ List < IconProperties > iconProperties = new List < IconProperties > ( ) ;
14
17
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 ++ )
27
19
{
20
+ IconProperties icon = new IconProperties ( ) ;
28
21
//get icon attributes
29
22
int listingStart = 6 + ( i * 16 ) ;
30
23
int width = bytes [ listingStart + 0 ] ;
@@ -33,6 +26,8 @@ public static void UnpackPngIcon(FileStream inputStream, string outputFolder, st
33
26
int height = bytes [ listingStart + 1 ] ;
34
27
if ( height == 0 ) { height = 256 ; }
35
28
29
+ //imageSize = Math.Max(width, height);
30
+
36
31
int size = bytes [ listingStart + 8 ] ;
37
32
size += bytes [ listingStart + 9 ] * 256 ;
38
33
size += bytes [ listingStart + 10 ] * 256 * 256 ;
@@ -41,65 +36,128 @@ public static void UnpackPngIcon(FileStream inputStream, string outputFolder, st
41
36
offset += bytes [ listingStart + 13 ] * 256 ;
42
37
offset += bytes [ listingStart + 14 ] * 256 * 256 ;
43
38
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
+ }
45
49
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 ) )
50
76
{
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 ++ )
53
78
{
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 ] ) ;
59
80
}
60
- output_stream . Close ( ) ;
81
+ bitmap_writer . Flush ( ) ;
61
82
}
62
-
83
+ output_stream . Close ( ) ;
63
84
}
64
85
}
65
86
66
87
67
88
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 )
69
90
{
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);
70
94
if ( UnpackAsPNG )
71
95
{
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
+ }
74
101
input_stream . Close ( ) ;
75
102
}
76
103
else
77
104
{
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 ) ;
79
113
}
80
-
81
114
}
82
115
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 )
84
117
{
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
+
86
125
try
87
126
{
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 ++ )
92
130
{
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
+ }
97
146
}
98
- }
147
+ //}
99
148
}
100
149
catch ( Exception ex )
101
150
{
102
151
Debug . WriteLine ( ex . Message ) ;
103
152
}
104
153
}
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
+ }
105
163
}
0 commit comments