apache poi ppt到png emf
我想问一下ApachePOI库。我有一个.pptx文件,根据我在互联网上找到的示例,我将每张幻灯片分割成单独的图像。当幻灯片包含.png、.jpeg图像时,这非常有效,但一旦幻灯片中有.emf文件,这张图像就会消失。因此,我希望有相同的幻灯片副本,但也有.emf文件。这可能吗 版本:ApachePOI3.12apache poi ppt到png emf,apache,apache-poi,Apache,Apache Poi,我想问一下ApachePOI库。我有一个.pptx文件,根据我在互联网上找到的示例,我将每张幻灯片分割成单独的图像。当幻灯片包含.png、.jpeg图像时,这非常有效,但一旦幻灯片中有.emf文件,这张图像就会消失。因此,我希望有相同的幻灯片副本,但也有.emf文件。这可能吗 版本:ApachePOI3.12 非常感谢如评论中所述,EMF不支持开箱即用。。。既然我们决定举行一次会议,那就不太可能了 在POI中,基本上有两个选项可以提供自定义图像渲染器: 通过setRenderingHint(D
非常感谢如评论中所述,EMF不支持开箱即用。。。既然我们决定举行一次会议,那就不太可能了 在POI中,基本上有两个选项可以提供自定义图像渲染器:
- 通过
在Graphics2D上下文中实现并注册实现。缺点是,任何图像都会调用它,而位图/wmf图像的默认处理方式则会丢失setRenderingHint(Drawable.IMAGE\u RENDERER,new MyImageRenderner())
- 或者提供一个为您自己的实现服务的自定义(如下面的示例所示),该自定义仅在必要时转移到EMF呈现程序
(看看这个例子,当前的POI ImageRenderer处理看起来并不灵活,与其拥有全局处理程序,不如为每个内容类型注册一个处理程序……)
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);
}
}
}
}
package org.apache.poi.xslf;
导入java.awt.Dimension;
导入java.awt.Graphics2D;
导入java.awt.Insets;
导入java.awt.RenderingHints;
导入java.awt.geom.AffineTransform;
导入java.awt.geom.Rectangle2D;
导入java.awt.image.buffereImage;
导入java.io.ByteArrayInputStream;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入javax.imageio.imageio;
导入org.apache.poi.sl.draw.DrawFactory;
导入org.apache.poi.sl.draw.DrawPictureShape;
导入org.apache.poi.sl.draw.Drawable;
导入org.apache.poi.sl.draw.ImageRenderer;
导入org.apache.poi.sl.usermodel.PictureData;
导入org.apache.poi.sl.usermodel.PictureData.PictureType;
导入org.apache.poi.sl.usermodel.PictureShape;
导入org.apache.poi.util.POILogFactory;
导入org.apache.poi.util.POILogger;
导入org.apache.poi.xslf.usermodel.xmlsideshow;
导入org.apache.poi.xslf.usermodel.XSLFPictureShape;
导入org.apache.poi.xslf.usermodel.XSLFSlide;
导入org.freehep.graphicsio.emf.EMFInputStream;
导入org.freehep.graphicsio.emf.EMFRenderer;
导入org.junit.Test;
公共类测试呈现{
私有最终静态POILogger LOG=POILogFactory.getLogger(TestEMFRender.class);
@试验
public void render()引发异常{
xmlsideshow ppt=getDummy();
维度pgsize=ppt.getPageSize();
buffereImage img=新的buffereImage((int)pgsize.getWidth(),(int)pgsize.getHeight(),buffereImage.TYPE_int_ARGB);
Graphics2D graphics=initGraphicsCtx(img);
//画画
getSlides().get(0).draw(图形);
//保存结果
File outfile=新文件(“bla.png”);
ImageIO.write(img,“PNG”,输出文件);
//清理
graphics.dispose();
img.flush();
ppt.close();
}
静态XMLSlideShow getDummy()引发IOException{
XMLSlideShow ppt=新的XMLSlideShow();
FileInputStream fis=新的FileInputStream(“kiwilogo.emf”);
picturedatapd=ppt.addPicture(fis,PictureType.EMF);
fis.close();
XSLFSlide sl=ppt.createSlide();
XSLFPictureShape ps=sl.createPicture(pd);
ps.setAnchor(新矩形2D双(100100100100));
返回ppt;
}
静态图形2D初始化图形SCTX(BuffereImage img){
Graphics2D graphics=img.createGraphics();
//默认渲染选项
graphics.setRenderingHint(RenderingHints.KEY\u抗锯齿,RenderingHints.VALUE\u抗锯齿开);
graphics.setRenderingHint(RenderingHints.KEY\u RENDERING,RenderingHints.VALUE\u RENDER\u QUALITY);
graphics.setRenderingHint(renderingHits.KEY\u插值,renderingHits.VALUE\u插值双三次);
graphics.setRenderingHint(renderingHits.KEY_-partitionlmetrics,renderingHits.VALUE_-partitionlmetrics_-ON);
//定制绘图工厂
DrawFactory df=新DrawFactory(){
公共绘图PictureShape getDrawable(PictureShape形状){
返回新的DrawPictureShapeEmf(形状);
}
};
graphics.setRenderingHint(Drawable.DRAW_工厂,df);
固定字体(图形);
返回图形;
}
静态类DrawPictureShapeEmf扩展了DrawPictureShape{
公共绘图PictureShapeEMF(PictureShape形状){
超级(形状);
}
@凌驾
公共内容(图形2D图形){
PictureData=getShape().getPictureData();
if(data==null)返回;
矩形2D锚点=getAnchor(图形,getShape());
Insets Insets=getShape().getClipping();
试一试{
字符串contentType=data.getContentType();
图像渲染器=
PictureType.EMF.contentType.equals(contentType)
?新IMGRender()
:super.getImageRenderer(图形,contentType);
renderer.loadImage(data.getData(),data.getContentType());
渲染器。drawImage(图形、锚定、插入);
}捕获(IOE异常){
LOG.LOG(POILogger.ERROR,“无法加载/渲染图像”,e);
}
}
}
静态类imgrender实现ImageRenderer{
EMFRenderer EMFRenderer;
公共void loadImage(InputStream数据,字符串contentType)引发IOException{
emfRenderer=新的emfRenderer(新的EMFInputStream(数据));
}
public void loadImage(字节[]数据,字符串contentType)引发IOException