首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我正在使用Apache POI将PPTX幻灯片转换为图像,但生成的图像非常大,超过1.5mb

我正在使用Apache POI将PPTX幻灯片转换为图像,但生成的图像非常大,超过1.5mb
EN

Stack Overflow用户
提问于 2020-04-15 19:37:51
回答 1查看 526关注 0票数 0

我已经通过一些在线工具转换了相同的pptx文件,为幻灯片生成的图像比通过POI生成的图像要少得多。

代码语言:javascript
复制
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();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-15 20:24:54

首先,从您的代码中删除ppt.write(out);。它将整个XMLSlideShow ppt写入到每个FileOutputStream outppt_image_*.jpg中。这是没有用的,只会给每个ppt_image_*.jpg文件添加不必要的字节。

如果大小不够小,您可以使用java.awt.geom.AffineTransform设置缩放比例因子,然后将该转换设置为使用的Graphics2D

代码语言:javascript
复制
...
Double zoom = .5d;
AffineTransform at = new AffineTransform();
at.setToScale(zoom, zoom);
...
Graphics2D graphics = img.createGraphics();
graphics.setTransform(at);
...

小于1d的缩放因子将导致较小的图像大小,因此文件大小也较小。

完整示例:

代码语言:javascript
复制
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;

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61227722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档