private static bool optimizeImage(PdfPaintedImage painted)
        {
            PdfImage image = painted.Image;

            // inline images can not be recompressed unless you move them to resources
            // using PdfCanvas.MoveInlineImagesToResources
            if (image.IsInline)
            {
                return(false);
            }

            // mask images are not good candidates for recompression
            if (image.IsMask || image.Width < 8 || image.Height < 8)
            {
                return(false);
            }

            // get size of the painted image
            int width  = Math.Max(1, (int)painted.Bounds.Width);
            int height = Math.Max(1, (int)painted.Bounds.Height);

            // calculate resize ratio
            double ratio = Math.Min(image.Width / (double)width, image.Height / (double)height);

            if (ratio <= 1)
            {
                // the image size is smaller then the painted size
                return(recompressImage(image));
            }

            if (ratio < 1.1)
            {
                // with ratio this small, the potential size reduction
                // usually does not justify resizing artefacts
                return(false);
            }

            if (image.Compression == PdfImageCompression.Group4Fax ||
                image.Compression == PdfImageCompression.Group3Fax ||
                image.Compression == PdfImageCompression.JBig2 ||
                (image.ComponentCount == 1 && image.BitsPerComponent == 1))
            {
                return(resizeBilevelImage(image, ratio));
            }

            int resizedWidth  = (int)Math.Floor(image.Width / ratio);
            int resizedHeight = (int)Math.Floor(image.Height / ratio);

            if ((image.ComponentCount >= 3 && image.BitsPerComponent == 8) || isGrayJpeg(image))
            {
                image.ResizeTo(resizedWidth, resizedHeight, PdfImageCompression.Jpeg, 90);
                // or image.ResizeTo(resizedWidth, resizedHeight, PdfImageCompression.Jpeg2000, 10);
            }
            else
            {
                image.ResizeTo(resizedWidth, resizedHeight, PdfImageCompression.Flate, 9);
            }

            return(true);
        }
        private static bool resizeBilevelImage(PdfImage image, double ratio)
        {
            // Fax documents usually look better if integer-ratio scaling is used
            // Fractional-ratio scaling introduces more artifacts
            int intRatio = (int)ratio;

            // decrease the ratio when it is too high
            if (intRatio > 3)
            {
                intRatio = Math.Min(intRatio - 2, 3);
            }

            if (intRatio == 1 && image.Compression == PdfImageCompression.Group4Fax)
            {
                // skipping the image, because the output size and compression are the same
                return(false);
            }

            image.ResizeTo(image.Width / intRatio, image.Height / intRatio, PdfImageCompression.Group4Fax);
            return(true);
        }
        private static bool optimizeImage(PdfPaintedImage painted, PdfDocument pdf)
        {
            PdfImage image = painted.Image;

            // inline images can not be recompressed unless you move them to resources
            // using PdfCanvas.MoveInlineImagesToResources
            if (image.IsInline)
            {
                return(false);
            }

            // mask images are not good candidates for recompression
            if (image.IsMask || image.Width < 8 || image.Height < 8)
            {
                return(false);
            }

            // get size of the painted image
            int width  = Math.Max(1, (int)painted.Bounds.Width);
            int height = Math.Max(1, (int)painted.Bounds.Height);

            if (width >= image.Width || height >= image.Height)
            {
                if (image.HasMask)
                {
                    return(false);
                }

                if (image.ComponentCount == 1 && image.BitsPerComponent == 1 &&
                    image.Compression != PdfImageCompression.Group4Fax)
                {
                    image.RecompressWithGroup4Fax();
                }
                else if (image.BitsPerComponent == 8 &&
                         image.ComponentCount >= 3 &&
                         image.Compression != PdfImageCompression.Jpeg &&
                         image.Compression != PdfImageCompression.Jpeg2000)
                {
                    image.RecompressWithJpeg2000(10);
                    // or image.RecompressWithJpeg();
                }

                return(true);
            }

            // try to replace large masked images
            if (image.HasMask)
            {
                if (image.Width < 300 || image.Height < 300)
                {
                    return(false);
                }

                using (var stream = new MemoryStream())
                {
                    PdfPage tempPage = pdf.AddPage();
                    tempPage.Canvas.DrawImage(image, 0, 0, width, height, 0);
                    PdfPaintedImage tempPaintedImage = tempPage.GetPaintedImages()[0];

                    tempPaintedImage.SaveAsPainted(stream);

                    pdf.RemovePage(pdf.PageCount - 1);

                    image.ReplaceWith(stream);
                    return(true);
                }
            }

            if (image.Compression == PdfImageCompression.Group4Fax ||
                image.Compression == PdfImageCompression.Group3Fax)
            {
                // Fax documents usually looks better if integer-ratio scaling is used
                // Fractional-ratio scaling introduces more artifacts
                int ratio = Math.Min(image.Width / width, image.Height / height);

                // decrease the ratio when it is too high
                if (ratio > 6)
                {
                    ratio -= 5;
                }
                else if (ratio > 3)
                {
                    ratio -= 2;
                }

                image.ResizeTo(image.Width / ratio, image.Height / ratio, PdfImageCompression.Group4Fax);
            }
            else if (image.ComponentCount >= 3 && image.BitsPerComponent == 8)
            {
                image.ResizeTo(width, height, PdfImageCompression.Jpeg, 90);
            }
            else
            {
                image.ResizeTo(width, height, PdfImageCompression.Flate, 9);
            }

            return(true);
        }
Exemplo n.º 4
0
        public static void Main()
        {
            // NOTE:
            // When used in trial mode, the library imposes some restrictions.
            // Please visit http://bitmiracle.com/pdf-library/trial-restrictions.aspx
            // for more information.

            const string originalFile   = @"Sample Data\jpeg.pdf";
            const string compressedFile = "CompressAllTechniques.pdf";

            using (var pdf = new PdfDocument(originalFile))
            {
                // 1. Recompress images
                foreach (PdfPage page in pdf.Pages)
                {
                    foreach (PdfPaintedImage painted in page.GetPaintedImages())
                    {
                        PdfImage image = painted.Image;
                        // image that is used as mask or image with attached mask are
                        // not good candidates for recompression
                        if (image.IsMask || image.Mask != null || image.Width < 8 || image.Height < 8)
                        {
                            continue;
                        }

                        // get size of the painted image
                        int width  = Math.Max(1, (int)painted.Bounds.Width);
                        int height = Math.Max(1, (int)painted.Bounds.Height);
                        if (width >= image.Width || height >= image.Height)
                        {
                            if (image.ComponentCount == 1 && image.BitsPerComponent == 1 &&
                                image.Compression != PdfImageCompression.Group4Fax)
                            {
                                image.RecompressWithGroup4Fax();
                            }
                            else if (image.BitsPerComponent == 8 &&
                                     image.ComponentCount >= 3 &&
                                     image.Compression != PdfImageCompression.Jpeg &&
                                     image.Compression != PdfImageCompression.Jpeg2000)
                            {
                                image.RecompressWithJpeg2000(10);
                                // or image.RecompressWithJpeg();
                            }
                        }
                        else
                        {
                            // NOTE: PdfImage.ResizeTo() method is not supported in version for .NET Standard
                            if (image.Compression == PdfImageCompression.Group4Fax ||
                                image.Compression == PdfImageCompression.Group3Fax)
                            {
                                // Fax documents usually looks better if integer-ratio scaling is used
                                // Fractional-ratio scaling introduces more artifacts
                                int ratio = Math.Min(image.Width / width, image.Height / height);
                                image.ResizeTo(image.Width / ratio, image.Height / ratio, PdfImageCompression.Group4Fax);
                            }
                            else if (image.ComponentCount >= 3 && image.BitsPerComponent == 8)
                            {
                                image.ResizeTo(width, height, PdfImageCompression.Jpeg, 90);
                            }
                            else
                            {
                                image.ResizeTo(width, height, PdfImageCompression.Flate, 9);
                            }
                        }
                    }
                }

                // 2 Setup save options
                pdf.SaveOptions.Compression             = PdfCompression.Flate;
                pdf.SaveOptions.UseObjectStreams        = true;
                pdf.SaveOptions.RemoveUnusedObjects     = true;
                pdf.SaveOptions.OptimizeIndirectObjects = true;
                pdf.SaveOptions.WriteWithoutFormatting  = true;

                // 3. Remove structure information
                pdf.RemoveStructureInformation();

                // 4. Flatten form fields
                // Controls become uneditable after that
                pdf.FlattenControls();

                // 5. Clear metadata
                pdf.Metadata.Basic.Clear();
                pdf.Metadata.DublinCore.Clear();
                pdf.Metadata.MediaManagement.Clear();
                pdf.Metadata.Pdf.Clear();
                pdf.Metadata.RightsManagement.Clear();
                pdf.Metadata.Custom.Properties.Clear();

                foreach (XmpSchema schema in pdf.Metadata.Schemas)
                {
                    schema.Properties.Clear();
                }

                pdf.Info.Clear(false);

                // 6. Remove font duplicates
                pdf.ReplaceDuplicateFonts();

                // 7. Unembed fonts
                foreach (PdfFont font in pdf.GetFonts())
                {
                    // Only unembed popular fonts installed in the typical OS. You can extend
                    // the list of such fonts in the "if" statement below.
                    if (font.Name == "Arial" || font.Name == "Verdana")
                    {
                        font.Unembed();
                    }
                }

                pdf.Save(compressedFile);
            }

            string message = string.Format(
                "Original file size: {0} bytes;\r\nCompressed file size: {1} bytes",
                new FileInfo(originalFile).Length,
                new FileInfo(compressedFile).Length
                );

            MessageBox.Show(message);

            Process.Start(compressedFile);
        }
        public static void Main()
        {
            // NOTE:
            // When used in trial mode, the library imposes some restrictions.
            // Please visit http://bitmiracle.com/pdf-library/trial-restrictions.aspx
            // for more information.

            const string originalFile   = @"Sample Data\jpeg.pdf";
            const string compressedFile = "OptimizeImages.pdf";

            using (PdfDocument pdf = new PdfDocument(originalFile))
            {
                foreach (PdfPage page in pdf.Pages)
                {
                    foreach (PdfPaintedImage painted in page.GetPaintedImages())
                    {
                        PdfImage image = painted.Image;

                        // inline images can not be recompressed unless you move them to resources
                        // using PdfCanvas.MoveInlineImagesToResources
                        if (image.IsInline)
                        {
                            continue;
                        }

                        // image that is used as mask or image with attached mask are
                        // not good candidates for recompression
                        if (image.IsMask || image.Mask != null || image.Width < 8 || image.Height < 8)
                        {
                            continue;
                        }

                        // get size of the painted image
                        int width  = Math.Max(1, (int)painted.Bounds.Width);
                        int height = Math.Max(1, (int)painted.Bounds.Height);
                        if (width >= image.Width || height >= image.Height)
                        {
                            if (image.ComponentCount == 1 && image.BitsPerComponent == 1 &&
                                image.Compression != PdfImageCompression.Group4Fax)
                            {
                                image.RecompressWithGroup4Fax();
                            }
                            else if (image.BitsPerComponent == 8 &&
                                     image.ComponentCount >= 3 &&
                                     image.Compression != PdfImageCompression.Jpeg &&
                                     image.Compression != PdfImageCompression.Jpeg2000)
                            {
                                image.RecompressWithJpeg2000(10);
                                // or image.RecompressWithJpeg();
                            }
                        }
                        else
                        {
                            if (image.Compression == PdfImageCompression.Group4Fax ||
                                image.Compression == PdfImageCompression.Group3Fax)
                            {
                                // Fax documents usually looks better if integer-ratio scaling is used
                                // Fractional-ratio scaling introduces more artifacts
                                int ratio = Math.Min(image.Width / width, image.Height / height);
                                image.ResizeTo(image.Width / ratio, image.Height / ratio, PdfImageCompression.Group4Fax);
                            }
                            else if (image.ComponentCount >= 3 && image.BitsPerComponent == 8)
                            {
                                image.ResizeTo(width, height, PdfImageCompression.Jpeg, 90);
                            }
                            else
                            {
                                image.ResizeTo(width, height, PdfImageCompression.Flate, 9);
                            }
                        }
                    }
                }

                pdf.Save(compressedFile);
            }

            string message = string.Format(
                "Original file size: {0} bytes;\r\nCompressed file size: {1} bytes",
                new FileInfo(originalFile).Length,
                new FileInfo(compressedFile).Length
                );

            MessageBox.Show(message);

            Process.Start(compressedFile);
        }