예제 #1
0
        private static Command ResizeImageCommand()
        {
            Command command = new Command("ResizeImage", "Save an image at a different size")
            {
                MyConsole.GetVerbosityOption(),
                new Option("--file", "The destination of the input image file to resize.")
                {
                    Argument = new Argument <FileInfo>("Location").ExistingOnly()
                },
                new Option("--output", "The destination for the output file (original extension will be appended).")
                {
                    Argument = new Argument <string>("Location")
                },
                new Option("--width", "The new width dimension. Required if --height is omitted.")
                {
                    Argument = new Argument <int>()
                },
                new Option("--height", "The new height dimension. Required if --width is omitted.")
                {
                    Argument = new Argument <int>()
                },
                new Option("--overwrite", @"When true, overwrites the existing file rather than creating a copy.
Cannot be used with --output.")
                {
                    Argument = new Argument <bool>()
                    {
                        Arity = ArgumentArity.ZeroOrOne,
                    },
                },
                new Option("--quality", @"The compression quality to apply to the new image.
Defaults to 100.")
                {
                    Argument = new Argument <long>()
                }
            };

            command.Handler = CommandHandler.Create((
                                                        FileInfo file,
                                                        string output,
                                                        int width,
                                                        int height,
                                                        long quality,
                                                        bool overwrite,
                                                        int v) =>
            {
                MyConsole.Verbosity = v;
                MyConsole.Debug($"Verbosity set to {v}");
                if (overwrite && output != default)
                {
                    MyConsole.Error("Cannot use --overwrite with --output");
                    return;
                }
                if (quality == default)
                {
                    quality = 100L;
                }
                ResizeImage.Exec(file, output, width, height, quality, overwrite);
            });
            return(command);
        }
예제 #2
0
 /// <summary>
 /// Create a new path relative to this file. If the <paramref name="output"/> file path is
 /// absolute, uses that alone. The extension of the original file is appended to the new file.
 /// </summary>
 /// <param name="file"></param>
 /// <param name="output"></param>
 /// <returns></returns>
 public static string CreateSavePath(this FileInfo file, string output = default)
 {
     MyConsole.Info($"Creating new save path: {file}->{output}");
     if (output == default)
     {
         MyConsole.Debug($"--output not supplied: calculating from original file name ({file}).");
         output = $"{Path.GetFileNameWithoutExtension(file.Name)}_copy";
     }
     MyConsole.Debug($"Given output: {output}");
     return(Path.Combine(
                Path.GetDirectoryName(file.FullName),
                $"{output}{Path.GetExtension(file.Name)}"));
 }
예제 #3
0
 private static ImageCodecInfo GetEncoder(ImageFormat format)
 {
     MyConsole.Debug($"Get Encoder for {format.Guid}");
     ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
     foreach (ImageCodecInfo codec in codecs)
     {
         MyConsole.Debug($"  - Trying Image Codec with FormatID: {codec.FormatID}.");
         if (codec.FormatID == format.Guid)
         {
             MyConsole.Debug($"  - Image Codec matched for {codec.FormatID}.");
             return(codec);
         }
     }
     MyConsole.Debug($"No encoder found for format.");
     return(null);
 }
예제 #4
0
        /// <summary>
        /// Resize the image to the specified width and height.
        /// <para>
        /// Source: https://stackoverflow.com/a/24199315/6789816
        /// </para>
        /// </summary>
        /// <param name="image">The image to resize.</param>
        /// <param name="width">The width to resize to.</param>
        /// <param name="height">The height to resize to.</param>
        /// <returns>The resized image.</returns>
        public static Bitmap Resize(this Image image, int width, int height)
        {
            MyConsole.Info($"Resizing image: {width}x{height}");
            MyConsole.Debug("Creating bitmap destination image.");
            Rectangle destRect  = new Rectangle(0, 0, width, height);
            Bitmap    destImage = new Bitmap(width, height);

            destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

            MyConsole.Debug("Get graphics from image.");
            using (Graphics graphics = Graphics.FromImage(destImage))
            {
                MyConsole.Debug(@"Setting up graphics modes:");
                graphics.CompositingMode = CompositingMode.SourceCopy;

                MyConsole.Debug("  - CompositingQuality: HighQuality");
                graphics.CompositingQuality = CompositingQuality.HighQuality;

                MyConsole.Debug("  - InterpolationMode: HighQualityBicubic");
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

                MyConsole.Debug("  - SmoothingMode: HighQuality");
                graphics.SmoothingMode = SmoothingMode.HighQuality;

                MyConsole.Debug("  - PixelOffsetMode: HighQuality");
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

                MyConsole.Debug("  - WrapMode: TileFlipXY");
                using ImageAttributes wrapMode = new ImageAttributes();
                wrapMode.SetWrapMode(WrapMode.TileFlipXY);

                MyConsole.Debug("Drawing image...");
                graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
                MyConsole.Debug("Image drawn.");
            }

            return(destImage);
        }
예제 #5
0
        /// <summary>
        /// Wrapper for saving a <see cref="Bitmap"/> as a JPEG file.
        /// <para>
        /// Source: https://docs.microsoft.com/en-us/dotnet/framework/winforms/advanced/how-to-set-jpeg-compression-level
        /// </para>
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="output"></param>
        /// <param name="quality"></param>
        public static void SaveJPEG(this Bitmap bitmap, string output, long quality)
        {
            MyConsole.Info($"Saving image as JPEG with {quality} compression quality.");

            MyConsole.Debug("Use ImageFormat.Jpeg encoder.");
            ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);

            // Create an Encoder object based on the GUID  for the Quality parameter category.
            MyConsole.Debug("Create a quality encoder.");
            Encoder myEncoder = Encoder.Quality;

            // Create an EncoderParameters object.
            // An EncoderParameters object has an array of EncoderParameter objects.
            // In this case, there is only one EncoderParameter object in the array.
            MyConsole.Debug("Declare 1 encoder parameter:");
            EncoderParameters myEncoderParameters = new EncoderParameters(1);
            EncoderParameter  myEncoderParameter  = new EncoderParameter(myEncoder, quality);

            MyConsole.Debug("  - Adding quality encoder.");
            myEncoderParameters.Param[0] = myEncoderParameter;
            MyConsole.Debug($"Saving bitmap to {output} with encoders.");
            bitmap.Save(output, jpgEncoder, myEncoderParameters);
        }
예제 #6
0
        /// <summary>
        /// Execute the image resize.
        /// </summary>
        /// <param name="file">The file to resize.</param>
        /// <param name="output">Where the new file will be written to</param>
        /// <param name="width">
        /// If zero, calculated to keep current apsect ratio with new height.
        /// </param>
        /// <param name="height">
        /// If zero, calculated to keep current apsect ratio with new width.
        /// </param>
        /// <param name="overwrite">
        /// When true, ignores the <paramref name="output"/> parameter and saves over the input
        /// <paramref name="file"/>.
        /// </param>
        public static void Exec(
            this FileInfo file,
            string output,
            int width,
            int height,
            long quality   = 100L,
            bool overwrite = false)
        {
            Console.WriteLine($"Resize image {file}");
            try
            {
                MyConsole.Debug($"inputs: {file} ({width}x{height}) @ {quality} compression.");
                if (file == default)
                {
                    MyConsole.Warning("You must supply an file with --file.");
                    throw new MissingFieldException();
                }
                if (width == default && height == default)
                {
                    MyConsole.Warning("You must supply one or more of the following options: --width --height");
                    throw new MissingFieldException();
                }

                MyConsole.Debug(@$ "Reading in image from " "{file.Name}" ".");
                using (Image image = Image.FromFile(file.FullName))
                {
                    MyConsole.Debug(@$ "Done reading image.");

                    MyConsole.Info($"Original dimensions: {image.Width}x{image.Height}");
                    MyConsole.Debug($"Checking for missing height or width.");
                    if (width == default)
                    {
                        MyConsole.Debug($"Width was {width}");
                        width = (int)(image.Width * (double)height / image.Height);
                        MyConsole.Debug($"Set width relative to new height: {width}");
                    }
                    if (height == default)
                    {
                        MyConsole.Debug($"Height was {height}");
                        height = (int)(image.Height * (double)width / image.Width);
                        MyConsole.Debug($"Set height relative to new width: {height}");
                    }

                    using Bitmap bitmap = image.Resize(width, height);

                    MyConsole.Info($"Saving image.");
                    if (overwrite)
                    {
                        MyConsole.Debug("Output to temporary file for overwrite later.");
                        output = file.FullName.Replace(file.Name, "temp_" + DateTime.Now.Ticks);
                    }
                    else
                    {
                        // Create a path for the output file.
                        output = file.CreateSavePath(output);
                    }

                    MyConsole.Debug($"Computed output: {output}");
                    MyConsole.Debug($"Saving bitmap");
                    bitmap.SaveJPEG(output, quality);
                }
                if (overwrite)
                {
                    MyConsole.Debug("Delete old file to overwrite with new.");
                    file.Delete();
                    MyConsole.Debug("Rename temporary file to previous file's name.");
                    File.Move(output, file.FullName);
                    output = file.FullName;
                }
                MyConsole.Success($@"Wrote image to: {output}");
            }
            catch (Exception e)
            {
                if (e is MissingFieldException || MyConsole.Verbosity < 1)
                {
                    MyConsole.Error("Failed to write image.");
                }
                else
                {
                    throw;
                }
            }
            Console.WriteLine("Done.");
        }