-
Notifications
You must be signed in to change notification settings - Fork 187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PowerPoint ファイルをスライドショーにすると真っ黒画像に変換される #770
Comments
あと、@koda-masaru さんの方でも過去に調べられたとは思いますが、私の手持ちの環境でも色々と試してみて、現象を整理したところ以下の結果になりました。 Windows 10PowerPointで編集時、フォントを変えずに保存している部分は文字化けする。フォントを変えた部分は文字化けしない。 macOS 10.12試した限りだと常に文字化けしない。 CentOS 7.3X Window System がインストールされていて、なおかつ日本語フォントがインストールされていなければ文字化けしない(もしかすると後述のフォント固定後だけ文字化けしないのかもしれません)。やったことは、CentOS Minimal をインストールして以下のコマンドを実行しました。
使用した PowerPoint は 2013 です。 |
余談ですが、Windows 10 については、特定のテキストをフォントを変えずに保存すると、なぜか POI にはフォント指定が Calibri として解釈されているようでした。このため日本語文字がないので□で出力されるように見えました。これが POI の実装に起因するのか、PowerPoint の仕様なのかまでは調べられませんでしたが、画像変換時にフォントを全て SansSerif などに固定すると文字化けしないようになりました(が、フォントが変わると元のスライドから見た目も変わります)。 |
@Monota さん
PRお願いします。
OSのデフォルトでフォントが決まるのかもしれません。私もいろいろ試してみたのですが、PowerPointでスライドショー作成するとレイアウトが崩れたり文字化けしたりすることが多く、私が運営している環境では「PDFだけにして」とお願いしてる感じです。 ただ、PDFでもちゃんと日本語環境がセットアップできていないと、日本語は文字化けするようです。 パワーポイントからの変換があまりに不安定な場合は、PDFだけにした方が良いのかもしれませんね。 |
@koda-masaru さん、ありがとうございます。PR お送りしました。 たしかに、Windows の PowerPoint だと Calibri が英語フォントのデフォルトのようです。 一応、フォントを固定にしたときのソースコードを貼り付けておきます。 for (Slide<?, ?> slide : slides) {
String title = slide.getTitle();
System.out.println("Rendering slide " + slideNo + (title == null ? "" : ": " + title));
for (Object obj : slide.getShapes()) {
if (obj instanceof XSLFAutoShape) {
XSLFAutoShape shape = (XSLFAutoShape) obj;
for (TextParagraph paragraph : shape.getTextParagraphs()) {
System.out.println(paragraph.getDefaultFontFamily());
for (Object run : paragraph.getTextRuns()) {
if (run instanceof XSLFTextRun) {
((XSLFTextRun) run).setFontFamily(Font.SANS_SERIF);
}
}
}
}
}
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
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);
slide.draw(graphics);
img.flush();
//ImageIOUtil.writeImage(img, outputDir.getAbsolutePath() + "/" + (slideNo) + ".png", 300);
super.writeImage(img, outputDir.getAbsolutePath() + "/" + (slideNo) + ".png");
graphics.dispose();
slideNo++;
} PowerPoint については、もとのデザインを完全に再現して画像変換するのは難しいかもしれないですね。中身を軽く見ることができる程度の位置づけなら便利かもしれません。 |
プルリクありがとうございました!次回のリリースに含まれますので、少々お待ち下さい。 |
ご対応ありがとうございました。 本件とても気になったのでもう少し調べてみたのですが、解決方法は見つかっていません。 に書いてあるようなフォントのフォールバックの仕組みを利用して、 for (Slide<?, ?> slide : slides) {
String title = slide.getTitle();
System.out.println("Rendering slide " + slideNo + (title == null ? "" : ": " + title));
GraphicsEnvironment globalEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
try (InputStream is = ClassLoader.getSystemResourceAsStream("font/ipagp.ttf")) {
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
globalEnvironment.registerFont(font);
} catch (FontFormatException ffe) {
ffe.printStackTrace();
}
Map<String,String> fallbackMap = new HashMap<String,String>();
fallbackMap.put("*", "IPAPGothic");
slide.getTitle();
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = img.createGraphics();
graphics.setRenderingHint(Drawable.FONT_FALLBACK, fallbackMap);
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);
slide.draw(graphics);
img.flush();
//ImageIOUtil.writeImage(img, outputDir.getAbsolutePath() + "/" + (slideNo) + ".png", 300);
super.writeImage(img, outputDir.getAbsolutePath() + "/" + (slideNo) + ".png");
graphics.dispose();
slideNo++;
} のように、フォントがない場合はローカルフォント(この場合は IPA Pゴシック)にフォールバックするようにすることで Windows では対応できました。しかし CUI しかない Linux では □ になるので、まだ不十分なようです。 そろそろ諦めようかなと思っていますが備忘録として残しておきます。 |
@Monota さん
いったん、本issueは次回のリリースでクローズとして、今後日本語のところで要望などが出てきたら、再度調べるということで良いかと思っています。(そのころには、ライブラリのバージョンも上がっているかもしれませんし) |
上記内容で問題ありません。 |
Release v1.10.0 pre1 としてリリースしたためクローズします。 |
現状、PowerPoint ファイルのスライドショー変換を行うと、ほぼ 100% の確率で真っ黒画像に変換されます。
PptxSlideShowParser の実装を見ると、
となっていて、Slide の内容を BufferedImage に反映していないように思いました。そこで以下のようにコードを変えたらスライドが生成されるようにはなったのですが、今度は #509 で指摘されているような事象が起きました。
おそらく d15d24a で修正する前の内容に一部戻ってしまうかなと思うのですが、こちら PR お送りした方が良いでしょうか?
The text was updated successfully, but these errors were encountered: