diff --git a/Daramee.IconGenerator/App.config b/Daramee.IconGenerator/App.config new file mode 100644 index 0000000..8324aa6 --- /dev/null +++ b/Daramee.IconGenerator/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Daramee.IconGenerator/App.xaml b/Daramee.IconGenerator/App.xaml new file mode 100644 index 0000000..0577a62 --- /dev/null +++ b/Daramee.IconGenerator/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/Daramee.IconGenerator/App.xaml.cs b/Daramee.IconGenerator/App.xaml.cs new file mode 100644 index 0000000..9eae748 --- /dev/null +++ b/Daramee.IconGenerator/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace Daramee.IconGenerator +{ + /// + /// App.xaml에 대한 상호 작용 논리 + /// + public partial class App : Application + { + } +} diff --git a/Daramee.IconGenerator/Daramee.IconGenerator.csproj b/Daramee.IconGenerator/Daramee.IconGenerator.csproj new file mode 100644 index 0000000..589b66f --- /dev/null +++ b/Daramee.IconGenerator/Daramee.IconGenerator.csproj @@ -0,0 +1,114 @@ + + + + + Debug + AnyCPU + {34109481-1F43-4408-BFB5-2965C344DB6B} + WinExe + Daramee.IconGenerator + IconGenerator + v4.6 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + Resources\MainIcon.ico + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + MainWindow.xaml + Code + + + + + Code + + + + + + + + False + Microsoft .NET Framework 4.6%28x86 및 x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + + \ No newline at end of file diff --git a/Daramee.IconGenerator/IconEncoder.cs b/Daramee.IconGenerator/IconEncoder.cs new file mode 100644 index 0000000..1ef7b7c --- /dev/null +++ b/Daramee.IconGenerator/IconEncoder.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace Daramee.IconGenerator +{ + public class IconEncoder : IDisposable + { + [StructLayout ( LayoutKind.Sequential, Pack = 1 )] + struct IconHeader + { + public ushort reserved, type, count; + } + + [StructLayout ( LayoutKind.Sequential, Pack = 1 )] + struct EntryHeader + { + public byte width; + public byte height; + public byte colorCount; + public byte reserved; + public ushort planes; + public ushort bitCount; + public uint sizeInBytes; + public uint fileOffset; + } + + Stream outputStream; + + List> entries; + + public IconEncoder ( string filename ) + : this ( new FileStream ( filename, FileMode.Create ) ) + { } + public IconEncoder ( Stream stream ) + { + outputStream = stream; + entries = new List> (); + } + + private Stream EncodeImageToPNG ( BitmapSource imageSource ) + { + PngBitmapEncoder encoder = new PngBitmapEncoder (); + encoder.Frames.Add ( BitmapFrame.Create ( imageSource ) ); + + MemoryStream stream = new MemoryStream (); + encoder.Save ( stream ); + stream.Position = 0; + + return stream; + } + + private void WriteToStream ( Stream stream, T s ) where T : struct + { + IntPtr alloc = Marshal.AllocHGlobal ( Marshal.SizeOf () ); + Marshal.StructureToPtr ( s, alloc, false ); + byte [] array = new byte [ Marshal.SizeOf () ]; + Marshal.Copy ( alloc, array, 0, array.Length ); + stream.Write ( array, 0, array.Length ); + Marshal.FreeHGlobal ( alloc ); + } + + private BitmapSource ConvertIndexedColorImage ( BitmapSource source ) + { + BitmapPalette myPalette = new BitmapPalette ( source, 256 ); + PixelFormat pixelFormat = PixelFormats.Indexed8; + if ( myPalette.Colors.Count < 2 ) + pixelFormat = PixelFormats.Indexed1; + else if ( myPalette.Colors.Count < 4 ) + pixelFormat = PixelFormats.Indexed2; + else if ( myPalette.Colors.Count < 16 ) + pixelFormat = PixelFormats.Indexed4; + else if ( myPalette.Colors.Count == 256 ) + return source; + + FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap (); + newFormatedBitmapSource.BeginInit (); + newFormatedBitmapSource.Source = source; + newFormatedBitmapSource.DestinationPalette = myPalette; + newFormatedBitmapSource.DestinationFormat = pixelFormat; + newFormatedBitmapSource.EndInit (); + + return newFormatedBitmapSource; + } + + public void InsertImage ( BitmapSource imageSource ) + { + //imageSource = ConvertIndexedColorImage ( imageSource ); + Stream stream = EncodeImageToPNG ( imageSource ); + + EntryHeader header = new EntryHeader + { + width = ( byte ) ( uint ) imageSource.Width, + height = ( byte ) ( uint ) imageSource.Height, + colorCount = ( byte ) ( imageSource.Palette != null ? imageSource.Palette.Colors.Count : 0 ), + planes = 1, + bitCount = 0, + sizeInBytes = ( uint ) stream.Length + }; + + entries.Add ( new KeyValuePair ( stream, header ) ); + } + + public void Encode () + { + IconHeader header = new IconHeader () + { + reserved = 0, + type = 1, + count = ( ushort ) entries.Count, + }; + WriteToStream ( outputStream, header ); + + uint totalWritten = ( uint ) Marshal.SizeOf () + + ( uint ) entries.Count * ( uint ) Marshal.SizeOf (); + foreach ( var pair in entries ) + { + var entryHeader = pair.Value; + entryHeader.fileOffset = totalWritten; + WriteToStream ( outputStream, entryHeader ); + totalWritten += ( uint ) pair.Key.Length; + } + byte [] buffer = new byte [ 4194304 ]; + foreach ( var pair in entries ) + { + var stream = pair.Key; + int totalCopy = 0; + while ( totalCopy < stream.Length ) + { + int read = stream.Read ( buffer, 0, buffer.Length ); + outputStream.Write ( buffer, 0, read ); + totalCopy += read; + } + } + + outputStream.Flush (); + } + + public void Dispose () + { + outputStream.Dispose (); + } + } +} diff --git a/Daramee.IconGenerator/MainWindow.xaml b/Daramee.IconGenerator/MainWindow.xaml new file mode 100644 index 0000000..1c9ccd9 --- /dev/null +++ b/Daramee.IconGenerator/MainWindow.xaml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +