Saltar al contenido

Comprima PDF existente usando programación C# usando bibliotecas gratuitas

Nuestro grupo de trabajo ha estado mucho tiempo investigando soluciones a tus dudas, te brindamos la soluciones así que esperamos resultarte de mucha ayuda.

Solución:

Aquí hay un enfoque para hacer esto (y esto debería funcionar sin importar el conjunto de herramientas que use):

Si tiene una imagen rgb de 24 bits o cmyk de 32 bits, haga lo siguiente:

  • determinar si la imagen es realmente lo que es. Si es cmyk, conviértalo a rgb. Si es rgb y realmente gris, conviértalo a gris. Si es gris o con paleta y solo tiene 2 colores reales, conviértalo a 1 bit. Si es gris y hay relativamente pocas variaciones de gris, considere convertirlo a 1 bit con una técnica de binarización adecuada.
  • mida las dimensiones de la imagen en relación con la forma en que se coloca en la página; si tiene 300 ppp o más, considere volver a muestrear la imagen a un tamaño más pequeño según la profundidad de bits de la imagen; por ejemplo, puede probablemente pase de 300 dpi gris o rgb a 200 dpi y no pierda demasiado detalle.
  • si tiene una imagen rgb que es realmente color, considere paletizarla.
  • Examine el contenido de la imagen para ver si puede ayudar a que sea más comprimible. Por ejemplo, si ejecuta una imagen en color/gris y refina muchos colores que se agrupan, considere suavizarlos. Si es gris o blanco y negro y contiene una serie de motas, considere eliminar las motas.
  • elija sabiamente su compresión final. JPEG2000 puede hacerlo mejor que JPEG. JBIG2 lo hace mucho mejor que G4. Flate es probablemente la mejor compresión no destructiva para grises. La mayoría de las implementaciones de JPEG2000 y JBIG2 son no gratis.
  • si eres una estrella de rock, quieres intentar segmentar la imagen y dividirla en áreas que son realmente en blanco y negro y en color.

Dicho esto, si puede hacer todo esto bien sin supervisión, tiene un producto comercial por derecho propio.

Diré que puede hacer la mayor parte de esto con Atalasoft dotImage (descargos de responsabilidad: no es gratis; trabajo allí; he escrito casi todas las herramientas de PDF; solía trabajar en Acrobat).

Una forma particular de hacerlo con dotImage es extraer todas las páginas que son solo imágenes, volver a comprimirlas y guardarlas en un nuevo PDF y luego crear un nuevo PDF tomando todas las páginas del documento original y reemplazándolas por las páginas recomprimidas, luego guardar de nuevo. No es tan dificil.

List pagesToReplace = new List();
PdfImageCollection pagesToEncode = new PdfImageCollection();

using (Document doc = new Document(sourceStream, password)) {

    for (int i=0; i < doc.Pages.Count; i++) 
        Page page = doc.Pages[i];
        if (page.SingleImageOnly) 
            pagesToReplace.Add(i);
            // a PDF image encapsulates an image an compression parameters
            PdfImage image = ProcessImage(sourceStream, doc, page, i);
            pagesToEncode.Add(i);
        
    

    PdfEncoder encoder = new PdfEncoder();
    encoder.Save(tempOutStream, pagesToEncode, null); // re-encoded pages
    tempOutStream.Seek(0, SeekOrigin.Begin);

    sourceStream.Seek(0, SeekOrigin.Begin);
    PdfDocument finalDoc = new PdfDocument(sourceStream, password);
    PdfDocument replacementPages = new PdfDocument(tempOutStream);

    for (int i=0; i < pagesToReplace.Count; i++) 
         finalDoc.Pages[pagesToReplace[i]] = replacementPages.Pages[i];
    

    finalDoc.Save(finalOutputStream);

Lo que falta aquí es ProcessImage(). ProcessImage rasterizará la página (y no necesitará comprender que la imagen podría haberse escalado para estar en el PDF) o extraerá la imagen (y rastreará la matriz de transformación en la imagen) y seguirá los pasos enumerados anteriormente. Esto no es trivial, pero es factible.

Creo que es posible que desee que sus clientes sepan que cualquiera de las bibliotecas que mencionó no es completamente gratuita:

  • iTextSharp tiene licencia AGPL, por lo que deber libere el código fuente de su solución o compre una licencia comercial.
  • PDFcompressNET es una biblioteca comercial.
  • pdftk tiene licencia GPL, por lo que deber libere el código fuente de su solución o compre una licencia comercial.
  • Docotic.Pdf es una biblioteca comercial.

Teniendo en cuenta todo lo anterior, supongo que puedo dejar software gratuito requisito.

Docotic.Pdf puede reducir el tamaño de archivos PDF comprimidos y sin comprimir en diferentes grados sin introducir ningún cambio destructivo.

Las ganancias dependen del tamaño y la estructura de un PDF: para archivos pequeños o archivos que en su mayoría son imágenes escaneadas, la reducción puede no ser tan grande, por lo que debe probar la biblioteca con sus archivos y ver por sí mismo.

Si lo que más le preocupa es el tamaño y hay muchas imágenes en sus archivos y está de acuerdo con perder parte de la calidad de esas imágenes, entonces puede volver a comprimir fácilmente las imágenes existentes usando Docotic.Pdf.

Aquí está el código que hace que todas las imágenes sean binivel y comprimidas con compresión de fax:

static void RecompressExistingImages(string fileName, string outputName)

    using (PdfDocument doc = new PdfDocument(fileName))
    
        foreach (PdfImage image in doc.Images)
            image.RecompressWithGroup4Fax();

        doc.Save(outputName);
    

también hay RecompressWithFlate, RecompressWithGroup3Fax y RecompressWithJpeg métodos.

La biblioteca convertirá las imágenes en color a dos niveles si es necesario. Puede especificar el nivel de compresión deflate, calidad JPEG, etc.

Docotic.Pdf también puede cambiar el tamaño de imágenes grandes (y volver a comprimirlas al mismo tiempo) en PDF. Esto podría ser útil si las imágenes de un documento son realmente más grandes de lo necesario o si la calidad de las imágenes no es tan importante.

A continuación se muestra un código que escala todas las imágenes que tienen un ancho o una altura mayor o igual a 256. Las imágenes escaladas se codifican luego mediante compresión JPEG.

public static void RecompressToJpeg(string path, string outputPath)

    using (PdfDocument doc = new PdfDocument(path))
    
        foreach (PdfImage image in doc.Images)
         image.Height >= 256))
                image.Scale(0.5, PdfImageCompression.Jpeg, 65);
        

        doc.Save(outputPath);
    

Las imágenes se pueden redimensionar al ancho y alto especificado usando uno de los ResizeTo métodos. Tenga en cuenta que ResizeTo El método no intentará preservar la relación de aspecto de las imágenes. Debe calcular el ancho y la altura adecuados usted mismo.

Descargo de responsabilidad: trabajo para Bit Miracle.

Calificaciones y comentarios

Recuerda que tienes la capacidad de comentar tu experiencia si te fue de ayuda.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *