压缩图片或pdf

压缩图片或pdf

 

{
    /// <summary>
    /// 压缩图片或pdf大小的Level
    /// </summary>
    public enum ReduceSizeLevel
    {
        Small,  //文件(小)
        Middle, //文件 (中)
        Large,   //文件 (大)
        None    //不压缩
    }

    public static class ReduceSizeHelper
    {

        #region 变量
       
        /// <summary>
        /// 图片的大小
        /// </summary>
        private static int[] Pix = new int[] { 1024, 1440, 1920 };

        /// <summary>
        /// 图片最小要求
        /// </summary>
        private static int[] PixMin = new int[] { 800, 1024, 1440 };

        /// <summary>
        /// 图片的质量
        /// </summary>
        private static int[] PicQuantity = new int[] { 90, 93, 96 };

        /// <summary>
        /// 调整后的文件大小
        /// </summary>
        private static int[] NewFileSize = new int[] { 204800, 409600, 614400 };

        #endregion

        #region 公共方法

        /// <summary>
        /// 压缩图片大小
        /// </summary>
        /// <param name="info"></param>
        /// <param name="ext"></param>
        public static void ReduceImageSize(VMCustLoanDocInfo info, string ext, ReduceSizeLevel level)
        {
            if (level == ReduceSizeLevel.None) return;
            int maxPix = 2400; //压缩后的尺寸
            int minPix = 800; //最小尺寸
            int quantity = 95; //质量百分比
            int maxFileSize = 204800; //压缩后的文件大小
            switch (level)
            {
                case ReduceSizeLevel.Small:
                    maxPix = Pix[0];
                    minPix = PixMin[0];
                    quantity = PicQuantity[0];
                    maxFileSize = NewFileSize[0];
                    break;
                case ReduceSizeLevel.Middle:
                    maxPix = Pix[1];
                    minPix = PixMin[1];
                    quantity = PicQuantity[1];
                    maxFileSize = NewFileSize[1];
                    break;
                case ReduceSizeLevel.Large:
                    maxPix = Pix[2];
                    minPix = PixMin[2];
                    quantity = PicQuantity[2];
                    maxFileSize = NewFileSize[2];
                    break;
                default:
                    break;
            }
            FileInfo fileInfo = new FileInfo(info.DocName);
            if (fileInfo.Length <= maxFileSize) return;

            IList<string> tmpFileNames = new List<string>();  //临时文件
            using (System.Drawing.Image img = ImageHelper.ResizeImage(System.Drawing.Image.FromFile(info.DocName), maxPix, maxPix))
            {
                info.TmpFileName = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache).TrimEnd('\\') + "\\" + Util.GetGuid() + ext;
                img.Save(info.TmpFileName);
                tmpFileNames.Add(info.TmpFileName);
            }
            string tmpFileName = info.TmpFileName;
            info.TmpFileName = reduceLoop(maxPix, minPix, quantity, maxFileSize, ref tmpFileNames, tmpFileName, ext);

            //删除临时文件
            foreach (string fileName in tmpFileNames)
            {
                if (fileName == info.TmpFileName) continue;
                try
                {
                    File.Delete(fileName);
                }
                catch { }
            }
        }

        /// <summary>
        /// 调整pdf里图片的大小
        /// </summary>
        /// <param name="info"></param>
        /// <param name="level"></param>
        public static void ReducePDFSize(VMCustLoanDocInfo info, ReduceSizeLevel level)
        {
            if (level == ReduceSizeLevel.None) return;
            int maxPix = 2400; //压缩后的尺寸
            int minPix = 800; //最小尺寸
            int quantity = 95; //质量百分比
            int maxFileSize = 204800; //压缩后的文件大小
            switch (level)
            {
                case ReduceSizeLevel.Small:
                    maxPix = Pix[0];
                    minPix = PixMin[0];
                    quantity = PicQuantity[0];
                    maxFileSize = NewFileSize[0];
                    break;
                case ReduceSizeLevel.Middle:
                    maxPix = Pix[1];
                    minPix = PixMin[1];
                    quantity = PicQuantity[1];
                    maxFileSize = NewFileSize[1];
                    break;
                case ReduceSizeLevel.Large:
                    maxPix = Pix[2];
                    minPix = PixMin[2];
                    quantity = PicQuantity[2];
                    maxFileSize = NewFileSize[2];
                    break;
                default:
                    break;
            }
            FileInfo fileInfo = new FileInfo(info.DocName);
            if (fileInfo.Length <= maxFileSize) return;

            IList<string> tmpFileNames = new List<string>();  //临时文件


            string imgExt = ".jpg";

            using (Aspose.Pdf.Document document = new Aspose.Pdf.Document(info.DocName))
            {
                if (fileInfo.Length <= maxFileSize * document.Pages.Count) return;
                foreach (Aspose.Pdf.Page page in document.Pages)
                {
                    int idx = 1;
                    foreach (Aspose.Pdf.XImage image in page.Resources.Images)
                    {
                        using (var imageStream = new MemoryStream())
                        {
                            // To compress images change the image type and resolution
                            image.Save(imageStream);
                            imageStream.Seek(0, SeekOrigin.Begin);
                            //// Control image quality for better compression

                            string tmpFileName = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache).TrimEnd('\\') + "\\" + Util.GetGuid() + imgExt;
                            tmpFileNames.Add(tmpFileName);
                            using (System.Drawing.Image img = System.Drawing.Image.FromStream(imageStream))
                            {
                                JXJR.CMS.Utility.ImageHelper.SaveJpeg(tmpFileName, img, 95);
                            }
                            tmpFileName = reduceLoop(maxPix, minPix, quantity, maxFileSize, ref tmpFileNames, tmpFileName, imgExt);
                            tmpFileNames.Add(tmpFileName);

                            using (FileStream newStream = new FileStream(tmpFileName, FileMode.Open))
                            {
                                page.Resources.Images.Replace(idx, newStream);
                            }
                        }

                        idx = idx + 1;
                    }
                }

                document.OptimizeResources();
                // save the updated file
                info.TmpFileName = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache).TrimEnd('\\') + "\\" + Util.GetGuid() + ".pdf";
                document.Save(info.TmpFileName);
                fileInfo = new FileInfo(info.DocName);
                long size1 = fileInfo.Length;
                fileInfo = new FileInfo(info.TmpFileName);
                long size2 = fileInfo.Length;
                if (size2 > size1)
                {
                    info.TmpFileName = info.DocName;
                }
            }
        }


        /// <summary>
        /// 把一个pdf分割成多个pdf
        /// </summary>
        /// <param name="pdfFileName">原始pdf文件名</param>
        /// <param name="newFileNamePrex">新pdf文件名的前面部分(后面部分是页码)</param>
        /// <param name="oneFilePageCount">分割后每个pdf文件包含的页数</param>
        /// <returns></returns>
        public static List<string> SplitPDFBarCode(string pdfFileName, string newFileNamePrex, int oneFilePageCount)
        {
            bool includeFirstPage = false;
            //分割后的存放路径
            List<string> tmpFileNames = new List<string>();
            if (!pdfFileName.ToLower().EndsWith(".pdf")) return tmpFileNames;

            using (Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(pdfFileName))
            {
                FileInfo fileInfo = new FileInfo(pdfFileName);
                if (!fileInfo.Exists) return tmpFileNames;
                newFileNamePrex = fileInfo.DirectoryName.EndsWith(@"\") ? fileInfo.DirectoryName + newFileNamePrex : fileInfo.DirectoryName + @"\" + newFileNamePrex;

                int i = includeFirstPage ? 1 : 2;  //includeFirstPage是false时 不含首页(可能是条形码页面)
                while (i <= pdfDocument.Pages.Count)
                {
                    int pageCount = 1;
                    using (Aspose.Pdf.Document newDocument = new Aspose.Pdf.Document())
                    {
                        int iFrom = i;
                        while (i <= pdfDocument.Pages.Count && pageCount <= oneFilePageCount)
                        {
                            Aspose.Pdf.Page pdfPage = pdfDocument.Pages[i];
                            newDocument.Pages.Add(pdfPage);
                            pageCount++;
                            i++;
                        }
                        string newFileName = newFileNamePrex;
                        if (pdfDocument.Pages.Count <= oneFilePageCount)
                        {
                            //不需要用页码标识
                            newFileName = newFileName + ".pdf";
                        }
                        else
                        {
                            if (includeFirstPage)
                            {
                                newFileName = oneFilePageCount > 1 ? newFileName + "_" + iFrom + "-" + (i - 1) + ".pdf" : newFileName + "_" + (i - 1) + ".pdf";
                            }
                            else
                            {
                                newFileName = oneFilePageCount > 1 ? newFileName + "_" + (iFrom - 1) + "-" + (i - 2) + ".pdf" : newFileName + "_" + (i - 2) + ".pdf";
                            }
                        }
                        if (File.Exists(newFileName))
                        {
                            try
                            {
                                File.Delete(newFileName);
                            }
                            catch
                            {
                                MyMessageBox.Warning("无法删除" + newFileName + ",文件可能已经被打开,请先关闭该文件");
                                return new List<string>();
                            }
                        }
                        newDocument.Save(newFileName);
                        tmpFileNames.Add(newFileName);
                    }
                }
                return tmpFileNames;
            }//using
        }


        /// <summary>
        /// 把一个pdf分割成多个pdf
        /// </summary>
        /// <param name="pdfFileName">原始pdf文件名</param>
        /// <param name="oneFilePageCount">分割后每个pdf文件包含的页数</param>
        /// <returns></returns>
        public static List<string> SplitPDF(string pdfFileName, int oneFilePageCount)
        {
            bool includeFirstPage = true;

            //分割后的存放路径
            List<string> tmpFileNames = new List<string>();
            if (!pdfFileName.ToLower().EndsWith(".pdf")) return tmpFileNames;

            using (Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(pdfFileName))
            {
                if (pdfDocument.Pages.Count <= oneFilePageCount)
                {
                    tmpFileNames.Add(pdfFileName);
                    return tmpFileNames;
                }
                FileInfo fileInfo = new FileInfo(pdfFileName);
                if (!fileInfo.Exists) return tmpFileNames;

                string newFileNamePrex = ""; //新pdf文件名的前面部分(后面部分是页码)
                newFileNamePrex = fileInfo.Name.Substring(0, fileInfo.Name.Length - fileInfo.Extension.Length);
                newFileNamePrex = fileInfo.DirectoryName.EndsWith(@"\") ? fileInfo.DirectoryName + newFileNamePrex : fileInfo.DirectoryName + @"\" + newFileNamePrex;

                int i = includeFirstPage ? 1 : 2;  //includeFirstPage是false时 不含首页(可能是条形码页面)
                while (i <= pdfDocument.Pages.Count)
                {
                    int pageCount = 1;
                    using (Aspose.Pdf.Document newDocument = new Aspose.Pdf.Document())
                    {
                        int iFrom = i;
                        while (i <= pdfDocument.Pages.Count && pageCount <= oneFilePageCount)
                        {
                            Aspose.Pdf.Page pdfPage = pdfDocument.Pages[i];
                            newDocument.Pages.Add(pdfPage);
                            pageCount++;
                            i++;
                        }
                        string newFileName = newFileNamePrex;
                        if (includeFirstPage)
                        {
                            newFileName = oneFilePageCount > 1 ? newFileName + "_" + iFrom + "-" + (i - 1) + ".pdf" : newFileName + "_" + (i - 1) + ".pdf";
                        }
                        else
                        {
                            newFileName = oneFilePageCount > 1 ? newFileName + "_" + (iFrom - 1) + "-" + (i - 2) + ".pdf" : newFileName + "_" + (i - 2) + ".pdf";
                        }
                        if (File.Exists(newFileName))
                        {
                            try
                            {
                                File.Delete(newFileName);
                            }
                            catch
                            {
                                MyMessageBox.Warning("无法删除" + newFileName + ",文件可能已经被打开,请先关闭该文件");
                                return new List<string>();
                            }
                        }
                        newDocument.Save(newFileName);
                        tmpFileNames.Add(newFileName);
                    }
                }
                return tmpFileNames;
            }//using
        }

        #endregion

        #region 私有方法
        
       
        /// <summary>
        /// 循环调整图片直到满足要求
        /// </summary>
        /// <param name="maxPix">最大分辨率</param>
        /// <param name="minPix">最小分辨率</param>
        /// <param name="quantity">图片质量百分比</param>
        /// <param name="maxFileSize">最大文件大小</param>
        /// <param name="tmpFileNames">调整过程中产生的临时文件</param>
        /// <param name="tmpFileName">初始文件名</param>
        /// <param name="ext">文件后缀名</param>
        /// <returns></returns>
        private static string reduceLoop(int maxPix, int minPix, int quantity, int maxFileSize, ref IList<string> tmpFileNames, string tmpFileName, string ext)
        {
            FileInfo fileInfo = new FileInfo(tmpFileName);
            while (fileInfo.Length > maxFileSize)  //循环,直到满足要求
            {
                if ((int)(maxPix * 0.9) > minPix) maxPix = (int)(maxPix * 0.9); //继续调整大小

                using (System.Drawing.Image img2 = ImageHelper.ResizeImage(System.Drawing.Image.FromFile(tmpFileName), maxPix, maxPix))
                {
                    tmpFileName = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache).TrimEnd('\\') + "\\" + Util.GetGuid() + ext;
                    img2.Save(tmpFileName);
                    tmpFileNames.Add(tmpFileName);
                    fileInfo = new FileInfo(tmpFileName);
                    if (fileInfo.Length > maxFileSize)
                    {
                        tmpFileName = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache).TrimEnd('\\') + "\\" + Util.GetGuid() + ext;
                        ImageHelper.SaveJpeg(tmpFileName, img2, quantity);
                        tmpFileNames.Add(tmpFileName);
                        fileInfo = new FileInfo(tmpFileName);
                        quantity -= 5; //再降低质量
                    }
                }//using img2
            }//while
            return tmpFileName;
        }

      

        ///// <summary>
        ///// 复制pdf文件
        ///// </summary>
        ///// <param name="docName"></param>
        ///// <param name="newFileNamePrex">pdf文件名(不含".pdf")</param>
        ///// <returns></returns>
        //public static string CopyPDF(string docName, string newFileNamePrex)
        //{
        //    FileInfo fileInfo = new FileInfo(docName);
        //    newFileNamePrex = fileInfo.DirectoryName.EndsWith(@"\") ? fileInfo.DirectoryName + newFileNamePrex : fileInfo.DirectoryName + @"\" + newFileNamePrex;
        //    newFileNamePrex += ".pdf";
        //    File.Copy(docName, newFileNamePrex, true);
        //    return newFileNamePrex;
        //}

        #endregion

    }
}
View Code

 

posted @ 2019-04-11 16:14  bxzjzg  阅读(164)  评论(0编辑  收藏  举报