2016-11-14 98 views
0

我想問一下關於圖書館的APACHE POI。我有一個.pptx文件和我在互聯網上找到的例子,我將每張幻燈片分成不同的圖像。當幻燈片contang.png,.jpeg圖像時,這工作得很好,但只要我在幻燈片中的.emf文件這個圖像消失。所以我想要有相同的幻燈片副本,但也要使用.emf文件。這可能嗎?apache poi ppt to png emf

版本:Apache的POI 3.12

非常感謝

+0

升級到最新版本的Apache POI,然後再試一次? – Gagravarr

+0

我做到了,但我想它不支持此功能 – tralalaUlalal

+0

EMF目前不支持開箱即用。 您需要藉助FreeHep庫提供您自己的ImageRenderer。 請參閱[如何使用FreeHep的示例](http://apache-poi.1045710.n5.nabble.com/ImageRender-for-EMF-convert-PPTX-slides-include-EMF-images-into- PNG-td5717773.html)和[如何提供自己的ImageRenderer](http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/ImageRenderer.java ?查看=標記) 我可能:)儘量想出一個詳細的答案很快 – kiwiwings

回答

0

正如評論所說,EMF不支持開箱即用...和FreeHep決定有LGPL license這是不可能的,我們將include in our release

在POI你基本上有兩種選擇,以提供自定義圖像渲染:

  • 實施,並通過setRenderingHint(Drawable.IMAGE_RENDERER, new MyImageRendener())註冊Graphics2D上下文ImageRenderer實施。其缺點是,它會被要求任何的圖像和你失去的默認處理位圖/ WMF圖像
  • 或提供自定義DrawFactory供應自己DrawPictureShape實施 - 如下面的例子 - 它只是轉移到EMF呈現在必要時
    看這個例子中,在當前POI ImageRenderer處理看起來並不靈活,而不是有一個全球性的處理器和,它可能會更好每個登記內容類型的處理程序...

除了usual POI component我已經包含freehep-graphics2d,freehep-graphicsbase,freehep-graphicsiofreehep-graphicsio-emffreehep-io

的例子還遠未完成,但我猜你至少腳踏啓動:

package org.apache.poi.xslf; 

import java.awt.Dimension; 
import java.awt.Graphics2D; 
import java.awt.Insets; 
import java.awt.RenderingHints; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.Rectangle2D; 
import java.awt.image.BufferedImage; 
import java.io.ByteArrayInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 

import javax.imageio.ImageIO; 

import org.apache.poi.sl.draw.DrawFactory; 
import org.apache.poi.sl.draw.DrawPictureShape; 
import org.apache.poi.sl.draw.Drawable; 
import org.apache.poi.sl.draw.ImageRenderer; 
import org.apache.poi.sl.usermodel.PictureData; 
import org.apache.poi.sl.usermodel.PictureData.PictureType; 
import org.apache.poi.sl.usermodel.PictureShape; 
import org.apache.poi.util.POILogFactory; 
import org.apache.poi.util.POILogger; 
import org.apache.poi.xslf.usermodel.XMLSlideShow; 
import org.apache.poi.xslf.usermodel.XSLFPictureShape; 
import org.apache.poi.xslf.usermodel.XSLFSlide; 
import org.freehep.graphicsio.emf.EMFInputStream; 
import org.freehep.graphicsio.emf.EMFRenderer; 
import org.junit.Test; 

public class TestEMFRender { 
    private final static POILogger LOG = POILogFactory.getLogger(TestEMFRender.class); 

    @Test 
    public void render() throws Exception { 
     XMLSlideShow ppt = getDummy(); 

     Dimension pgsize = ppt.getPageSize(); 
     BufferedImage img = new BufferedImage((int)pgsize.getWidth(), (int)pgsize.getHeight(), BufferedImage.TYPE_INT_ARGB); 
     Graphics2D graphics = initGraphicsCtx(img); 

     // draw stuff 
     ppt.getSlides().get(0).draw(graphics); 

     // save the result 
     File outfile = new File("bla.png"); 
     ImageIO.write(img, "PNG", outfile); 

     // cleanup 
     graphics.dispose(); 
     img.flush(); 
     ppt.close(); 
    } 

    static XMLSlideShow getDummy() throws IOException { 
     XMLSlideShow ppt = new XMLSlideShow(); 
     FileInputStream fis = new FileInputStream("kiwilogo.emf"); 
     PictureData pd = ppt.addPicture(fis, PictureType.EMF); 
     fis.close(); 
     XSLFSlide sl = ppt.createSlide(); 
     XSLFPictureShape ps = sl.createPicture(pd); 
     ps.setAnchor(new Rectangle2D.Double(100, 100, 100, 100)); 
     return ppt; 
    } 

    static Graphics2D initGraphicsCtx(BufferedImage img) { 
     Graphics2D graphics = img.createGraphics(); 
     // default rendering options 
     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); 

     // custom draw factory 
     DrawFactory df = new DrawFactory(){ 
      public DrawPictureShape getDrawable(PictureShape<?,?> shape) { 
       return new DrawPictureShapeEmf(shape); 
      } 
     }; 
     graphics.setRenderingHint(Drawable.DRAW_FACTORY, df); 

     df.fixFonts(graphics); 

     return graphics; 
    } 

    static class DrawPictureShapeEmf extends DrawPictureShape { 
     public DrawPictureShapeEmf(PictureShape<?,?> shape) { 
      super(shape); 
     } 


     @Override 
     public void drawContent(Graphics2D graphics) { 
      PictureData data = getShape().getPictureData(); 
      if(data == null) return; 

      Rectangle2D anchor = getAnchor(graphics, getShape()); 
      Insets insets = getShape().getClipping(); 

      try { 
       String contentType = data.getContentType(); 
       ImageRenderer renderer = 
        PictureType.EMF.contentType.equals(contentType) 
        ? new ImgRenderer() 
        : super.getImageRenderer(graphics, contentType); 

       renderer.loadImage(data.getData(), data.getContentType()); 
       renderer.drawImage(graphics, anchor, insets); 
      } catch (IOException e) { 
       LOG.log(POILogger.ERROR, "image can't be loaded/rendered.", e); 
      } 
     } 

    } 


    static class ImgRenderer implements ImageRenderer { 
     EMFRenderer emfRenderer; 

     public void loadImage(InputStream data, String contentType) throws IOException { 
      emfRenderer = new EMFRenderer(new EMFInputStream(data)); 
     } 

     public void loadImage(byte[] data, String contentType) throws IOException { 
      loadImage(new ByteArrayInputStream(data), contentType); 
     } 

     public Dimension getDimension() { 
      return emfRenderer.getSize(); 
     } 

     public void setAlpha(double alpha) { 
     } 

     public BufferedImage getImage() { 
      return null; 
     } 

     public BufferedImage getImage(Dimension dim) { 
      return null; 
     } 

     public boolean drawImage(Graphics2D ctx, Rectangle2D graphicsBounds) { 
      return drawImage(ctx, graphicsBounds, null); 
     } 

     public boolean drawImage(Graphics2D ctx, Rectangle2D graphicsBounds, Insets clip) { 
      AffineTransform at = ctx.getTransform(); 
      try { 
       Dimension emfDim = emfRenderer.getSize(); 
       // scale output bounds to image bounds 
       ctx.translate(graphicsBounds.getX(), graphicsBounds.getY()); 
       ctx.scale(graphicsBounds.getWidth()/emfDim.getWidth(), graphicsBounds.getHeight()/emfDim.getHeight()); 

       // TODO: handle clipping 

       emfRenderer.paint(ctx); 

       return true; 
      } catch (RuntimeException e) { 
       // TODO: logging 
       return false; 
      } finally { 
       ctx.setTransform(at); 
      } 
     } 

    } 
} 
+0

非常感謝。但是這種解決方案可能嗎?使用函數ppt.getPictureData()我得到了所有的圖片在演示文稿中,而我發現只有圖片哪個.emf擴展名。我將它轉換爲svg與freehep和從svg到jpg,但現在我需要用新的.jpg替換舊的.emf與函數picture.setData(newImageStream),但我不知道這是否會工作 – tralalaUlalal

+0

因此,在您的新問題你想用JPG替換emf圖像,對嗎?所以,只需簡單地調整我的方法即可從FreeHeps EMFRenderer獲取JPG並更改字節和內容類型 - 我想您必須遍歷所有幻燈片並更改那裏的參考。 如果這是你想要的,然後打開一個新的問題,我可能會採用代碼... – kiwiwings

+0

是的,我現在得到它:) ...但在版本apache寶3.15的問題是,這種轉換後不工作從ppt轉換 - >圖像中的圖像仍然缺少文件,但與3.13版本正在工作everyting OK :) ..所以,感謝您的時間:) – tralalaUlalal