c# - 我必须压缩 PNG 文件图像,而不会降低质量

标签 c# image compression png

我想压缩 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)
            {
            }
        }

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

Bitmap bmp1 = new Bitmap(imageFile);//pathOfImage);
ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Png);

请有人帮助我。如果有新的方法,我欢迎。如果能改变这一点,那就更好了。

最佳答案

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);
}

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

关于c# - 我必须压缩 PNG 文件图像,而不会降低质量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32500469/

相关文章:

c# - 从 OracleDataAdapter.Fill() 填充 DataTable 时为 "Specified cast is not valid"

c# - 将对象转换为 XML 字符串

c# - Jquery 数据表 ASP.NET Gridview 大型数据集

version-control - 视频编辑工作的版本控制

html - 在保持比例的情况下在 html 中生成 "thumbnail"

hadoop - Hive查询时如何知道数据文件是如何压缩的

zip - 从 Inno Setup 中创建 ZIP 文件

c# - 将参数传递给用户控件

java - 如何在 Java 中将 TIFF 转换为 JPEG/PNG

java - 输入字符串压缩为字符串