我想問一下關於圖書館的APACHE POI。我有一個.pptx文件和我在互聯網上找到的例子,我將每張幻燈片分成不同的圖像。當幻燈片contang.png,.jpeg圖像時,這工作得很好,但只要我在幻燈片中的.emf文件這個圖像消失。所以我想要有相同的幻燈片副本,但也要使用.emf文件。這可能嗎?apache poi ppt to png emf
版本:Apache的POI 3.12
非常感謝
我想問一下關於圖書館的APACHE POI。我有一個.pptx文件和我在互聯網上找到的例子,我將每張幻燈片分成不同的圖像。當幻燈片contang.png,.jpeg圖像時,這工作得很好,但只要我在幻燈片中的.emf文件這個圖像消失。所以我想要有相同的幻燈片副本,但也要使用.emf文件。這可能嗎?apache poi ppt to png emf
版本:Apache的POI 3.12
非常感謝
正如評論所說,EMF不支持開箱即用...和FreeHep決定有LGPL license這是不可能的,我們將include in our release。
在POI你基本上有兩種選擇,以提供自定義圖像渲染:
setRenderingHint(Drawable.IMAGE_RENDERER, new MyImageRendener())
註冊Graphics2D上下文ImageRenderer實施。其缺點是,它會被要求任何的圖像和你失去的默認處理位圖/ WMF圖像除了usual POI component我已經包含freehep-graphics2d,freehep-graphicsbase,freehep-graphicsio,freehep-graphicsio-emf和freehep-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);
}
}
}
}
非常感謝。但是這種解決方案可能嗎?使用函數ppt.getPictureData()我得到了所有的圖片在演示文稿中,而我發現只有圖片哪個.emf擴展名。我將它轉換爲svg與freehep和從svg到jpg,但現在我需要用新的.jpg替換舊的.emf與函數picture.setData(newImageStream),但我不知道這是否會工作 – tralalaUlalal
因此,在您的新問題你想用JPG替換emf圖像,對嗎?所以,只需簡單地調整我的方法即可從FreeHeps EMFRenderer獲取JPG並更改字節和內容類型 - 我想您必須遍歷所有幻燈片並更改那裏的參考。 如果這是你想要的,然後打開一個新的問題,我可能會採用代碼... – kiwiwings
是的,我現在得到它:) ...但在版本apache寶3.15的問題是,這種轉換後不工作從ppt轉換 - >圖像中的圖像仍然缺少文件,但與3.13版本正在工作everyting OK :) ..所以,感謝您的時間:) – tralalaUlalal
升級到最新版本的Apache POI,然後再試一次? – Gagravarr
我做到了,但我想它不支持此功能 – tralalaUlalal
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