Я использую Apache POI для преобразования слайдов PPTX в изображения, но размер сгенерированных изображений довольно велик - более 1,5 МБ - PullRequest
0 голосов
/ 15 апреля 2020

Я преобразовал тот же файл pptx через некоторые онлайн-инструменты, и сгенерированные изображения для слайдов намного меньше, чем сгенерированные с помощью POI.

try {
        //creating an empty presentation
        //File file = new File("/Users/dk/Documents/Jitendra/work/Rough/download_images/pptx1.pptx");
        XMLSlideShow ppt = new XMLSlideShow(new FileInputStream("lighthouse_tobeused.pptx"));

        //getting the dimensions and size of the slide
        Dimension pgsize = ppt.getPageSize();
        List<XSLFSlide> slide = ppt.getSlides();

        BufferedImage img = null;

        int imgWidth = pgsize.width;
        int imgHeight = pgsize.height;

        for (int i = 0; i < slide.size(); i++) {
            LOG.info("imgWidth => "+imgWidth+" ,imgHeight => "+imgHeight);

            img = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics = img.createGraphics();

            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);

            graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            graphics.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST, 150);


            graphics.setColor(Color.white);
            graphics.clearRect(0, 0, imgWidth, imgHeight);
            graphics.fill(new Rectangle2D.Float(0, 0, imgWidth, imgHeight));

            //render
            slide.get(i).draw(graphics);

           FileOutputStream out = new FileOutputStream("ppt_image_"+i+".jpg");
            javax.imageio.ImageIO.write(img, "jpg", out);
            ppt.write(out);
            //LOG.info("Image successfully created");
            out.close();

1 Ответ

1 голос
/ 15 апреля 2020

Сначала удалите ppt.write(out); из вашего кода. Это записывает все XMLSlideShow ppt в FileOutputStream out для каждого ppt_image_*.jpg. Это бесполезно и добавляет только ненужные байты к каждому из ppt_image_*.jpg файлов.

Если размер не достаточно мал, вы можете использовать java.awt.geom.AffineTransform, чтобы установить коэффициент масштабирования масштабирования, а затем установить преобразование в используемый Graphics2D.

...
Double zoom = .5d;
AffineTransform at = new AffineTransform();
at.setToScale(zoom, zoom);
...
Graphics2D graphics = img.createGraphics();
graphics.setTransform(at);
...

Коэффициент масштабирования ниже 1d приведет к уменьшению размера изображения и, соответственно, к уменьшению размера файла.

Полный пример:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.geom.AffineTransform;
import java.awt.RenderingHints;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.imageio.ImageIO;

import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;

public class PptToImage {

   public static void main(String args[]) throws Exception {

      FileInputStream in =new FileInputStream("PPTX.pptx");
      XMLSlideShow ppt = new XMLSlideShow(in);

      //set zoom factor
      Double zoom = .5d;
      AffineTransform at = new AffineTransform();
      at.setToScale(zoom, zoom);

      //get the dimension of size of the slide 
      Dimension pgsize = ppt.getPageSize();

      //get slides 
      java.util.List<XSLFSlide> slides = ppt.getSlides();

      BufferedImage img = null;
      FileOutputStream out = null;

      for (int i = 0; i < slides.size(); i++) {
         img = new BufferedImage((int)Math.ceil(pgsize.width * zoom), (int)Math.ceil(pgsize.height * zoom), BufferedImage.TYPE_INT_RGB);
         Graphics2D graphics = img.createGraphics();

         //set scaling transform
         graphics.setTransform(at);

         graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
         graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
         graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);

         graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
         graphics.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST, 150);

         //clear the drawing area
         graphics.setPaint(Color.white);
         graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));

         //render
         slides.get(i).draw(graphics);

         //creating an image file as output
         out = new FileOutputStream("ppt_image_" + i + ".png");
         ImageIO.write(img, "png", out);
         out.close();   
      }
   }
}

Играю с разными Double zoom = .5d;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...