我编写了一个将PPTX转换为PNG的程序。所有的转换都很好,唯一的问题是PPTX文件中有UNICODE字符 - 它将其转换为垃圾字符。这是代码。我试图添加字体,但没有帮助。这就是PPTX包含的内容 - “ /ˌinəvāSHən/ ”。它将字母i,n,v,a,S,H,n转换为精细但不是其他字母。
FileInputStream is = new FileInputStream(strTempPath);
XMLSlideShow pptx = new XMLSlideShow(is);
is.close();
double zoom = 2; // magnify it by 2
AffineTransform at = new AffineTransform();
at.setToScale(zoom, zoom);
Dimension pgsize = pptx.getPageSize();
XSLFSlide[] slide = pptx.getSlides();
}
// BufferedImage img = new BufferedImage((int)Math.ceil(pgsize.width*zoom), (int)Math.ceil(pgsize.height*zoom), BufferedImage.TYPE_INT_RGB);
BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
//graphics.setTransform(at);
graphics.setPaint(Color.white);
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
slide[iPageNo].draw(graphics);
// FileOutputStream output = new ByteArrayOutputStream("C:/Temp/aspose/word/slide-" + (10 + 1) + ".png");
output = new ByteArrayOutputStream();
javax.imageio.ImageIO.write(img, "png", output);
这就是我尝试添加字体但仍未转换的方式。
Font customFont = Font.createFont(Font.TRUETYPE_FONT, new File("/usr/share/fonts/GEInspRg.ttf")).deriveFont(12f);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
//register the font
ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("/usr/share/fonts/GEInspRg.ttf")));
graphics.setFont(customFont);
这是我的代码:原始问题中也给出了:我的测试PPTX包含了这个词 - /ˌinəvāSHən/以及其他英文字母。
package foo;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
public class PPTXToPNG {
public static void main(String[] args) throws Exception {
FileInputStream is = new FileInputStream("C:/Temp/PPTXToImage/unicode_test.pptx");
XMLSlideShow ppt = new XMLSlideShow(is);
is.close();
double zoom = 2;
AffineTransform at = new AffineTransform();
at.setToScale(zoom, zoom);
Dimension pgsize = ppt.getPageSize();
XSLFSlide[] slide = ppt.getSlides();
BufferedImage img = new BufferedImage((int)Math.ceil(pgsize.width*zoom),
(int)Math.ceil(pgsize.height*zoom), BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
graphics.setTransform(at);
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
// Draw first page in the PPTX. First page starts at 0 position
slide[0].draw(graphics);
FileOutputStream out = new FileOutputStream("C:/Temp/PPTXToImage/ConvertedSlide.png");
javax.imageio.ImageIO.write(img, "png", out);
out.close();
System.out.println("DONE");
}
}
答案 0 :(得分:2)
正如Jongware上面指出的那样,字符不能以“GE Inspira”字体显示,正如您在下面的示例程序中看到的那样 - 所以你需要一些/ˌinəvāSHən/(创新)来到那;)
我可以考虑几种方法:
我不确定用于设置代码的graphics.setFont(customFont);
是否只是一个测试,但通常POI将使用(并设置)文档中指定的字体。因此最简单的方法是用支持语音的字体替换原始文档中的字体(有关合适的字体,请参阅wikipedia unicode article)。顺便说一句。如果您尝试在Libre Office中使用该字体并插入这些语音,您也将获得“垃圾”字符。
您可以使用类似fontforge的内容将缺少的字符添加到您喜欢的字体中,使用不同的字体(但当然需要使用它 - 见上文)。它看起来有点奇怪,但比矩形更好......
您可以事先检查指定字体的text-runs are supported中的某些字符,并为不支持的字符插入带有替代字体的新文本运行元素
我知道PDF正在进行某种字体替换,如果找不到字体(甚至字符???),我还没有找到类似java的机制。简短搜索...也许还有这样的解决方案......
(用POI 3.10-beta1测试)
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.io.*;
import org.apache.poi.xslf.usermodel.*;
public class UnicodePPT {
public static void main(String[] args) throws Exception {
// create a sample pptx
XMLSlideShow ss = new XMLSlideShow();
Dimension pgsize = ss.getPageSize();
XSLFSlide slide = ss.createSlide();
XSLFTextBox tb = slide.createTextBox();
tb.setShapeType(XSLFShapeType.HEART);
int shapeSize = 150;
tb.setAnchor(new Rectangle2D.Double(pgsize.getWidth()/2-shapeSize/2, pgsize.getHeight()/2-shapeSize/2, shapeSize, shapeSize));
tb.setLineWidth(2);
tb.setLineColor(Color.BLACK);
XSLFTextParagraph par = tb.addNewTextParagraph();
tb.setVerticalAlignment(VerticalAlignment.DISTRIBUTED);
par.setTextAlign(TextAlign.CENTER);
XSLFTextRun run = par.addNewTextRun();
run.setText("/\u02CCin\u0259\u02C8v\u0101SH\u0259n/");
run.setFontFamily("DejaVu Serif");
run.setFontSize(12);
par.addLineBreak();
run = par.addNewTextRun();
run.setText("/\u02CCin\u0259\u02C8v\u0101SH\u0259n/");
run.setFontFamily("GE Inspira");
run.setFontSize(12);
// set the font
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
InputStream is = new FileInputStream("src/main/resources/GEInspRg.TTF");
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
is.close();
ge.registerFont(font);
is = new FileInputStream("src/main/resources/DejaVuSerif.ttf");
font = Font.createFont(Font.TRUETYPE_FONT, is);
is.close();
ge.registerFont(font);
// render it
double zoom = 2; // magnify it by 2
AffineTransform at = new AffineTransform();
at.setToScale(zoom, zoom);
BufferedImage img = new BufferedImage((int)Math.ceil(pgsize.width*zoom), (int)Math.ceil(pgsize.height*zoom), BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
graphics.setTransform(at);
graphics.setPaint(Color.white);
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
slide.draw(graphics);
FileOutputStream fos = new FileOutputStream("unicodeppt.png");
javax.imageio.ImageIO.write(img, "png", fos);
fos.close();
}
}