Как уменьшить размер png изображения в pdf (сжать png в pdf)JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Как уменьшить размер png изображения в pdf (сжать png в pdf)

Сообщение Anonymous »

Я хочу уменьшить размер PDF-файла, заменив изображение с высоким разрешением изображением с более низким разрешением. Чтобы решить проблему, мне нужно:
  • извлечь изображения (потоки) из pdf
  • сжать изображения
  • заменить изображения (потоки) в PDF сжатыми изображениями
Когда Я извлекаю изображения PNG и заменяю их, прозрачный фон меняется на черный. Я извлекаю изображения из PDF-файла, чтобы выяснить причину. Есть что-то очень странное, что pdf использует для потоковой передачи для сохранения png. Поэтому, если я попытаюсь извлечь изображение PNG из PDF-файла, я получу два разных изображения: 8-битное цветное изображение и 24-битное цветное изображение.

...
1 0 obj
stream
...
endstream
endobj
2 0 obj
stream
...
endstream
...


Исходное изображение (32-битное цветное изображение с прозрачным фоном):

[img]https: //i.sstatic.net/OXpND.png[/img]


8-битное цветное изображение:
Изображение


24-битное цветное изображение:

< img alt="24-битный цвет" src="https://i.sstatic.net/eRKCN.png" />


com.itextpdf
itextpdf
5.5.12


org.apache.pdfbox
pdfbox
2.0.16



ImageExtractor поможет вам извлечь изображения из файла PDF.

public class ImageExtractor {

private static final Logger log = LoggerFactory.getLogger(ImageExtractor.class);

public void extract(File pdf, File imageDir) throws IOException {
if(!imageDir.exists()) {
imageDir.mkdirs();
}
PDDocument document = PDDocument.load(pdf);
PDPageTree list = document.getPages();
System.out.println("PDPageTree#count: " + list.getCount());
int pageIndex = 1;
for (PDPage page : list) {
PDResources pdResources = page.getResources();
System.out.println(pdResources.toString());
for (COSName c : pdResources.getXObjectNames()) {
System.out.println("PDResources[" + pageIndex + "]#COSName: " + c.getName());
PDXObject o = pdResources.getXObject(c);
System.out.println("PDResources[" + pageIndex + "]#PDXObject: " + o.toString());
// https://github.com/mkl-public/testarea- ... ction.java
if (o instanceof PDImageXObject) {
PDImageXObject img = (PDImageXObject) o;
File file = new File(imageDir, pageIndex + "-" + System.nanoTime() + "." + img.getSuffix());
ImageIO.write(((PDImageXObject)o).getImage(), img.getSuffix(), file);
}
}
pageIndex ++;
}
log.info("Images have been extracted successfully! Check your images folder.");
}
}


ReplaceHightResolutionImage — это код, который я использую для уменьшения размера PDF-файла.

package io.gitlab.donespeak.tutorial.pdf.reducesize.itext;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfStream;
import com.itextpdf.text.pdf.parser.PdfImageObject;
import io.gitlab.donespeak.tutorial.pdf.reducesize.imagecompress.ImageCompressor;
import io.gitlab.donespeak.tutorial.pdf.reducesize.imagecompress.SimpleCompress;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ReplaceHightResolutionImage {

private ImageCompressor compressor;
private double quality;
private double scale;

public ReplaceHightResolutionImage(double quality, double scale) {
this.compressor = new SimpleCompress();
this.quality = quality;
this.scale = scale;
}

public ReplaceHightResolutionImage(double quality, double scale, ImageCompressor compressor) {
this.compressor = compressor;
this.quality = quality;
this.scale = scale;
}

public void replace(File pdf, File output) throws IOException, DocumentException {
PdfReader reader = new PdfReader(new FileInputStream(pdf));
int n = reader.getXrefSize();
PdfObject object;
PRStream stream;

for (int i = 0; i < n; i++) {

object = reader.getPdfObject(i);
stream = findImageStream(object);
if (stream == null) {
continue;
}
PdfImageObject pdfImageObject = new PdfImageObject(stream);
BufferedImage bi = pdfImageObject.getBufferedImage();
if (bi == null) {
continue;
}
System.out.println("PdfReader#Xref: " + i + "," + pdfImageObject.getFileType());
BufferedImage resultImage = compressor.compress(bi, pdfImageObject.getFileType(), quality, scale);
replaceImage(stream, resultImage);
}

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(output));
// furtherCompress(reader, stamper);
stamper.close();
}

private void furtherCompress(PdfReader reader, PdfStamper stamper) throws DocumentException {
reader.removeFields();
reader.removeUnusedObjects();
stamper.setFullCompression();
stamper.getWriter().setCompressionLevel(PdfStream.DEFAULT_COMPRESSION);
}

private PRStream findImageStream(PdfObject object) {
PRStream stream;
if (object == null || !object.isStream()) {
return null;
}
stream = (PRStream)object;
System.out.println(stream.getAsName(PdfName.SUBTYPE));
if (!PdfName.IMAGE.equals(stream.getAsName(PdfName.SUBTYPE))) {
// not jpg or png
return null;
}
PdfName pdfName = stream.getAsName(PdfName.FILTER);
if (!PdfName.DCTDECODE.equals(pdfName) && !PdfName.FLATEDECODE.equals(pdfName)) {
return null;
}
// if (PdfName.DCTDECODE.equals(filter)) {
// return PdfImageObject.ImageBytesType.JPG.getFileExtension();
// } else if (PdfName.JPXDECODE.equals(filter)) {
// return PdfImageObject.ImageBytesType.JP2.getFileExtension();
// } else if (PdfName.FLATEDECODE.equals(filter)) {
// return PdfImageObject.ImageBytesType.PNG.getFileExtension();
// } else if (PdfName.LZWDECODE.equals(filter)) {
// return PdfImageObject.ImageBytesType.CCITT.getFileExtension();
// }
return stream;
}

private void replaceImage(PRStream stream, BufferedImage resultImage) throws IOException {

ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();
ImageIO.write(resultImage, "JPG", imgBytes);

stream.clear();
stream.setData(imgBytes.toByteArray(), false, PRStream.NO_COMPRESSION);
stream.put(PdfName.TYPE, PdfName.XOBJECT);
stream.put(PdfName.SUBTYPE, PdfName.IMAGE);
stream.put(PdfName.FILTER, PdfName.DCTDECODE);
stream.put(PdfName.WIDTH, new PdfNumber(resultImage.getWidth()));
stream.put(PdfName.HEIGHT, new PdfNumber(resultImage.getHeight()));
stream.put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
stream.put(PdfName.COLORSPACE, PdfName.DEVICERGB);
}
}


package io.gitlab.donespeak.tutorial.pdf.reducesize.itext;

public class ThumbnailatorCompressor implements ImageCompressor {

@Override
public BufferedImage compress(BufferedImage image, String imageFormat, double quality, double scale) throws IOException {
System.out.println("ThumbnailatorCompressor#type: " + image.getType());
// int imageType = "png".equalsIgnoreCase(imageFormat)? BufferedImage.TYPE_INT_ARGB: image.getType();
BufferedImage thumbnail = Thumbnails.of(image)
.imageType(image.getType())
.scale(scale)
.outputQuality(quality)
// .outputFormat(imageFormat)
.useOriginalFormat()
.asBufferedImage();

return thumbnail;
}
}



[*]horse.pdf
[*]horse.png


public class ReplaceHightResolutionImageTest {

@Test
public void reduceWithThumbnailatorCompressor() throws IOException, DocumentException {
double quality = 1d;
double scale = 0.6d;
File pdf = new File("pdf/asset/horse.pdf");
File output = new File("pdf/target/output", "replaced-" + quality + "-" + scale);
ReplaceHightResolutionImage replacer = new ReplaceHightResolutionImage(quality, scale, new SimpleCompress());
replacer.replace(pdf, output);
}
}


Подробнее здесь: https://stackoverflow.com/questions/615 ... png-in-pdf
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»