我必须压缩PNG文件图像,而不会失去质量

Muh*_*hir 4 c# compression png image

我想压缩PNG图像,以减小其大小,但质量应保持不变.我试图压缩JPEG图片.图片压缩了大约90%,质量保持不变,但是当我用它压缩PNG图像时.没有结果,没有压缩.大小相同.

这是我的代码.

public const string _StatusLog = "StatusLog.csv";
        static void Main(string[] args)
        {
            Console.WriteLine("                 ###   WELCOME   ###");
            Console.Write("\n\nPlease enter image folder path :");
            string imagePath = Console.ReadLine();
            Program p = new Program();
            p.VaryQualityLevel(imagePath);
            Console.ReadLine();
        }
        private void VaryQualityLevel(string pathOfImage)
        {
            try
            {
                //Console.Write("Target Directory Path :");
                string targetDirectory = pathOfImage;//Console.ReadLine();

                if (targetDirectory != null)
                {
                    string[] allDirectoryInTargetDirectory = Directory.GetDirectories(targetDirectory);
                    //PRODUCT DIRECOTY OPEN
                    Console.Write("Total Folders found = " + allDirectoryInTargetDirectory.Count());
                    Console.Read();
                    if (allDirectoryInTargetDirectory.Any())
                    {
                        foreach (var directory in allDirectoryInTargetDirectory)
                        {
                            string[] subDirectory = Directory.GetDirectories(directory); // ATTRIBUTE DIRECTORY OPEN
                            if (subDirectory.Any())
                            {
                                foreach (var filesInSubDir in subDirectory)
                                {
                                    string[] allFilesInSubDir = Directory.GetFiles(filesInSubDir);
                                    //FILES IN SUB DIR OPEN
                                    if (allFilesInSubDir.Any())
                                    {
                                        foreach (var imageFile in allFilesInSubDir)
                                        {
                                            try
                                            {
                                                Bitmap bmp1 = new Bitmap(imageFile);//pathOfImage);
                                                ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);

                                                // Create an Encoder object based on the GUID 
                                                // for the Quality parameter category.
                                                System.Drawing.Imaging.Encoder myEncoder =
                                                    System.Drawing.Imaging.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.



                                                #region SAVING THE COMPRESS IMAGE FILE
                                                EncoderParameters myEncoderParameters = new EncoderParameters(1);

                                                EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
                                                myEncoderParameters.Param[0] = myEncoderParameter;

                                                bmp1.Save(filesInSubDir + "\\" + "Zip" + GettingImageNameForOptimizedImage(imageFile), jpgEncoder, myEncoderParameters);//pathOfImage
                                                Console.WriteLine(filesInSubDir + GettingImageNameForOptimizedImage(imageFile) + "  CREATED");//pathOfImage 
                                                #endregion

                                                #region DELETING THE ORIGNAL FILE
                                                bmp1.Dispose();
                                                System.IO.File.Delete(filesInSubDir + "\\" + GettingImageNameForOptimizedImage(imageFile));//pathOfImage
                                                Console.WriteLine(imageFile.Replace("jpg", "png") + "  DELETED");//pathOfImage 
                                                #endregion
                                                //myEncoderParameter = new EncoderParameter(myEncoder, 100L);
                                                //myEncoderParameters.Param[0] = myEncoderParameter;
                                                //bmp1.Save("D:\\" + RemovingImageFormat[0] + "100L" + ".jpg", jpgEncoder, myEncoderParameters);

                                                #region BACK RENAMING FILE TO ORIGNAL NAME
                                                System.IO.File.Move(filesInSubDir + "\\" + "Zip" + GettingImageNameForOptimizedImage(imageFile), filesInSubDir + "\\" + GettingImageNameForOptimizedImage(imageFile)); 
                                                #endregion
                                            }
                                            catch (Exception ex)
                                            {
                                                Console.Write("\n" + ex.Message + " Press enter to continue :");
                                                Console.ReadLine();

                                                Console.Write("\nWould you like to retry ? [Y/N] :");
                                                string resp = Console.ReadLine();
                                                if (resp == "Y" || resp == "y")
                                                {
                                                    Console.WriteLine("                 -------------------\n\n");
                                                    Main(null);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Write(ex);
                Console.Read();
            }

            Console.Write("Press any key to exit...");
            Console.Read();
            // Get a bitmap. ###################################################################


        }
        private ImageCodecInfo GetEncoder(ImageFormat format)
        {

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }
        public string GettingImageNameForOptimizedImage(string pathOfImage)
        {
            try
            {
                string[] splitingPathOfImage = pathOfImage.Split('\\');
                string[] RemovingImageFormat = splitingPathOfImage[splitingPathOfImage.Count() - 1].ToString().Split('.');
                return RemovingImageFormat[0] + ".jpg";
            }
            catch (Exception)
            {
                return null;
            }
            return null;
        }
        public static void LoggingOperations(string ImageName, string Status, bool UpdateRequired)
        {
            try
            {
                if (!File.Exists(_StatusLog))
                {
                    using (File.Create(_StatusLog)) { }
                    DirectorySecurity sec = Directory.GetAccessControl(_StatusLog);
                    SecurityIdentifier everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
                    sec.AddAccessRule(new FileSystemAccessRule(everyone, FileSystemRights.Modify | FileSystemRights.Synchronize, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
                    Directory.SetAccessControl(_StatusLog, sec);
                }
                if (UpdateRequired == true)
                {
                    string UpdateStatusText = File.ReadAllText(_StatusLog);
                    UpdateStatusText = UpdateStatusText.Replace(ImageName, ImageName + "," + Status);
                    File.WriteAllText(_StatusLog, UpdateStatusText);
                    UpdateStatusText = "";
                }
                else
                {
                    File.AppendAllText(_StatusLog, Environment.NewLine);
                    File.AppendAllText(_StatusLog, Status);
                }
            }
            catch (Exception)
            {
            }
        }
Run Code Online (Sandbox Code Playgroud)

对于PNG压缩,我更改了以下行.

Bitmap bmp1 = new Bitmap(imageFile);//pathOfImage);
ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Png);
Run Code Online (Sandbox Code Playgroud)

请帮助我的人.如果有新方法,我欢迎它.如果这可以改变,那就更好了.

Eti*_*ont 9

PNG图像默认为32位.您可以将它们转换为8位:结果文件将比原始文件小5倍.对于大多数图像,质量损失几乎是不可见的.

这就是在线png压缩机的作用.

您可以使用nQuant自己完成此操作:http://nquant.codeplex.com/ (Nuget上提供)

var quantizer = new WuQuantizer();         
using(var quantized = quantizer.QuantizeImage(bmp1))
{
    quantized.Save(targetPath, ImageFormat.Png);
}
Run Code Online (Sandbox Code Playgroud)

有关该方法的完整说明,请参见此博客文章http://www.hurryupandwait.io/blog/convert-32-bit-pngs-to-high-quality-8-bit-pngs-with-c

  • 感谢您提出nQuant。我刚试过 .NET在创建具有alpha透明性的800kb PNG的情况下,nQuant能够以240kb的速度创建相同的PNG图像,而没有明显的质量损失。请记住,它是通过将颜色数减少到256来实现的,但是它非常聪明。 (2认同)