示例#1
0
        public static void Main(string[] args)
        {
            if (args.Length < 1 || args.Length > 2)
            {
                Console.WriteLine("Parameters not matching!");
                Console.WriteLine("Usage: IcoEncoderCLI.exe <SourceImagePath> [<OutputPath>]");
                return;
            }

            string sourceFilePath = Path.GetFullPath(args[0]);
            string icoFilePath;

            if (args.Length >= 2)
            {
                icoFilePath = Path.GetFullPath(args[1]);
            }
            else
            {
                string directoryPath = Path.GetDirectoryName(sourceFilePath);
                icoFilePath = Path.Combine(directoryPath, Path.GetFileNameWithoutExtension(sourceFilePath) + ".ico");
            }

            using var icoStream = File.OpenWrite(icoFilePath);
            var icoEncoder = new IcoEncoder(icoStream);

            EncodeImageForResolution(icoEncoder, new WICSize(256, 256), sourceFilePath);

            icoEncoder.Commit();
        }
示例#2
0
        private static void DoCutFrames(ParseContext context, CommandLineOptions opts)
        {
            var length = new FileInfo(context.FullPath).Length;

            if (length > FileFormatConstants.MaxIcoFileSize)
            {
                Reporter.WarnLine(IcoErrorCode.FileTooLarge, $"Skipping file because it is unusually large ({length} bytes).", context.DisplayedPath);
                return;
            }

            var data = File.ReadAllBytes(context.FullPath);

            IcoDecoder.DoFile(data, context, frame => context.GeneratedFrames.Add(frame));

            var originalNumFrames = context.GeneratedFrames.Count;

            var indexes = from i in opts.FrameNumbersToDelete
                          orderby i descending
                          group i by i into g
                          select g.First();

            foreach (var i in indexes)
            {
                if (i > context.GeneratedFrames.Count)
                {
                    Reporter.WarnLine(IcoErrorCode.InvalidFrameIndex, $"Can't remove frame #{i} because the file only has {originalNumFrames}.", context.DisplayedPath);
                }
                else if (i < 1)
                {
                    Reporter.WarnLine(IcoErrorCode.InvalidFrameIndex, $"#{i} is not a valid frame number.", context.DisplayedPath);
                }
                else
                {
                    context.GeneratedFrames.RemoveAt(i - 1);
                }
            }

            if (opts.SizesToDelete != null)
            {
                context.GeneratedFrames.RemoveAll(f => opts.SizesToDelete.Any(s => s == f.Encoding.ClaimedHeight || s == f.Encoding.ClaimedWidth));
            }

            if (opts.BitDepthsToDelete != null)
            {
                context.GeneratedFrames.RemoveAll(f => opts.BitDepthsToDelete.Any(s => s == f.Encoding.ClaimedBitDepth));
            }

            if (!context.GeneratedFrames.Any())
            {
                Reporter.WarnLine(IcoErrorCode.ZeroFrames, $"There are no frames remaining; this file will be unreadable by most apps.", context.DisplayedPath);
            }

            IcoEncoder.EmitIco(context.FullPath, context);

            Reporter.InfoLine($"Removed {originalNumFrames - context.GeneratedFrames.Count} frame(s).", context.DisplayedPath);
        }
示例#3
0
        public void Test(string fileName, int width, int height)
        {
            string pngFilePath = TestUtil.GetResourceFilePath(fileName);

            using var pngStream = File.OpenRead(pngFilePath);

            string icoFilePath = TestUtil.GetTestFilePath(Path.GetFileName(pngFilePath) + ".ico");

            using (var icoStream = File.OpenWrite(icoFilePath))
            {
                var icoEncoder = new IcoEncoder(icoStream);
                icoEncoder.AddImage(new ImageInfo(pngStream, (byte)width, (byte)height, 0, 32));
                icoEncoder.Commit();
            }

            ValidateIcoFile(icoFilePath, width, height);
        }
示例#4
0
        private static void DoFile(byte[] data, ParseContext context, CommandLineOptions opts)
        {
            IcoDecoder.DoFile(data, context, frame => ProcessFrame(context, opts, frame));

            var outputPath = opts.OverwriteInputFiles
                ? context.FullPath
                : $"{context.FullPath}.crushed.ico";

            if (opts.DryRun)
            {
                Reporter.InfoLine($"Dry run: not writing output [{outputPath}]");
            }
            else
            {
                IcoEncoder.EmitIco(outputPath, context);
            }
        }
示例#5
0
        private static void EncodeImageForResolution(IcoEncoder icoEncoder, WICSize resolution, string sourceImagePath)
        {
            using var sourceImageStream = File.OpenRead(sourceImagePath);

            var sourceImageDecoder = wic.CreateDecoderFromStream(sourceImageStream, WICDecodeOptions.WICDecodeMetadataCacheOnLoad);

            var pngImageStream = new MemoryStream();

            var pngEncoder = wic.CreateEncoder(ContainerFormat.Png);

            pngEncoder.Initialize(pngImageStream, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);

            var pngImage = pngEncoder.CreateNewFrame();

            pngImage.Initialize();
            pngImage.SetPixelFormat(WICPixelFormat.WICPixelFormat32bppBGRA);
            pngImage.SetSize(resolution.Width, resolution.Height);

            var sourceImage = sourceImageDecoder.GetFrame(0);

            if (sourceImage.GetSize().Equals(resolution))
            {
                pngImage.WriteSource(sourceImage);
            }
            else
            {
                var scaler = wic.CreateBitmapScaler();
                scaler.Initialize(sourceImage, resolution, WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor);
                pngImage.WriteSource(scaler);
            }

            pngImage.Commit();
            pngEncoder.Commit();
            pngImageStream.Flush();

            byte width  = (byte)(resolution.Width == 256 ? 0 : resolution.Width);
            byte height = (byte)(resolution.Height == 256 ? 0 : resolution.Height);

            icoEncoder.AddImage(new ImageInfo(pngImageStream, width, height, 0, 32));
        }
示例#6
0
        private static int Run(CommandLineOptions opts)
        {
            if (opts.EncodingOverrideString != null)
            {
                switch (opts.EncodingOverrideString.ToLowerInvariant())
                {
                case "bitmap":
                case "bmp":
                    opts.EncodingOverride = IcoEncodingType.Bitmap;
                    break;

                case "png":
                    break;

                default:
                    Reporter.ErrorLine(IcoErrorCode.UnsupportedCodec, $"Invalid encoding type: {opts.EncodingOverrideString}");
                    return(1);
                }
            }

            if (opts.BitmapEncodingString != null)
            {
                switch (opts.BitmapEncodingString.ToLowerInvariant())
                {
                case "indexed1":
                    opts.BitmapEncodingOverride = BitmapEncoding.Pixel_indexed1;
                    break;

                case "indexed2":
                    opts.BitmapEncodingOverride = BitmapEncoding.Pixel_indexed2;
                    break;

                case "indexed4":
                    opts.BitmapEncodingOverride = BitmapEncoding.Pixel_indexed4;
                    break;

                case "indexed8":
                    opts.BitmapEncodingOverride = BitmapEncoding.Pixel_indexed8;
                    break;

                case "rgb555":
                    opts.BitmapEncodingOverride = BitmapEncoding.Pixel_rgb15;
                    break;

                case "rgb888":
                    opts.BitmapEncodingOverride = BitmapEncoding.Pixel_rgb24;
                    break;

                case "0rgb8888":
                    opts.BitmapEncodingOverride = BitmapEncoding.Pixel_0rgb32;
                    break;

                case "argb8888":
                    opts.BitmapEncodingOverride = BitmapEncoding.Pixel_argb32;
                    break;

                default:
                    Reporter.ErrorLine(IcoErrorCode.UnsupportedBitmapEncoding, $"Invalid bitamp encoding: {opts.BitmapEncodingString}");
                    return(1);
                }
            }

            var context = new ParseContext
            {
                DisplayedPath   = opts.InputFile,
                FullPath        = opts.InputFile,
                GeneratedFrames = new List <IcoFrame>(),
                Reporter        = Reporter,
                PngEncoder      = new SixLabors.ImageSharp.Formats.Png.PngEncoder
                {
                    CompressionLevel = 9,
                    ColorType        = SixLabors.ImageSharp.Formats.Png.PngColorType.RgbWithAlpha,
                },
            };

            if (File.Exists(opts.InputFile))
            {
                var data = File.ReadAllBytes(opts.InputFile);
                IcoDecoder.DoFile(data, context, frame => context.GeneratedFrames.Add(frame));
            }

            var newFrame = GenerateFrame(opts, context);

            if (opts.FrameIndex.HasValue)
            {
                if (opts.FrameIndex.Value < 1 || opts.FrameIndex.Value - 1 > context.GeneratedFrames.Count)
                {
                    Reporter.ErrorLine(IcoErrorCode.InvalidFrameIndex, $"Cannot insert frame at #{opts.FrameIndex.Value}. The icon has {context.GeneratedFrames.Count} frame(s).", opts.InputFile);
                    return(1);
                }

                context.GeneratedFrames.Insert(opts.FrameIndex.Value - 1, newFrame);
            }
            else
            {
                context.GeneratedFrames.Add(newFrame);
            }

            IcoEncoder.EmitIco(opts.InputFile, context);

            Reporter.PrintHelpUrls();
            return(0);
        }