java - 如何使用 apache poi 将背景图像设置为居中

标签 java image apache apache-poi

例如:

幻灯片尺寸:950 x 510

图像尺寸:500 x 4620

这是我的代码

XSLFPictureData idx = ppt.addPicture(file, pictureType);
CTBackgroundProperties bgPr = this.slide.getXmlObject().getCSld().addNewBg().addNewBgPr();
CTBlipFillProperties blipPr = bgPr.addNewBlipFill();
CTBlip blib = blipPr.addNewBlip();
CTRelativeRect ctRelativeRect = blipPr.addNewStretch().addNewFillRect();

double imgHeight =  idx.getImageDimensionInPixels().getHeight();
double imgWidth  =  idx.getImageDimensionInPixels().getWidth();
double pptHeight =  ppt.getPageSize().getHeight();
double pptWidth  =  ppt.getPageSize().getWidth();

if (pptHeight - imgHeight < 0) {
    //How to calculate the offset above and below the image
    ctRelativeRect.setT(?);
    ctRelativeRect.setB(?);
}else if(pptWidth - imgWidth < 0) {
    //
    ctRelativeRect.setR(?);
    ctRelativeRect.setL(?);
}

RelationPart rp = slide.addRelation(null, XSLFRelation.IMAGES, idx);
blib.setEmbed(rp.getRelationship().getId());

我不知道如何计算图像的偏移量,可以使其居中。 请给我一些建议。

这是图片: enter image description here

这是我想要的效果: enter image description here

最佳答案

CTRelativeRect 被命名为相对的,因为它的尺寸以幻灯片高度和幻灯片宽度的百分比表示。 您的长图像将被拉伸(stretch)或压缩到这些百分比尺寸。此外,所有向左、向右、顶部和底部的偏移量均以幻灯片高度和幻灯片宽度的百分比表示。

正如您所显示的想要的效果,图像应填充整个幻灯片宽度。因此图片宽度将从 500px 拉伸(stretch)到 950px。该比率为 950/500。以相同的比例,高度也会被拉伸(stretch)。

知道这一点后,我们需要将图片尺寸从像素计算为幻灯片尺寸的百分比。知道了这一点,我们就可以计算顶部偏移量为(100% - 图片高度百分比)/2。如果设置了相同的底部偏移量,那么长图片的确切中间将显示在幻灯片背景中。如果顶部偏移量为 (100% - 以 % 表示的图片高度)/2) - 100%,底部偏移量为 (100% - 以 % 表示的图片高度)/2 + 100%,则幻灯片背景将显示长边中间下方 1 个幻灯片高度图片。

除此之外,Microsoft 总是考虑到它自己奇怪的测量单位。由于避免使用 float 表示百分比,因此此处的测量单位为千分之一。

示例:

import java.io.FileOutputStream;
import java.io.FileInputStream;

import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.sl.usermodel.*;

import org.openxmlformats.schemas.presentationml.x2006.main.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;

import java.awt.Dimension;

public class CreatePPTXSheetsBackgroundPicture {

 public static void main(String[] args) throws Exception {

  XMLSlideShow slideShow = new XMLSlideShow();
  XSLFPictureData pictureData = slideShow.addPicture(new FileInputStream("2hGsR.jpg"), PictureData.PictureType.JPEG);
  slideShow.setPageSize(new Dimension(950, 510));

  double imgHeight =  pictureData.getImageDimensionInPixels().getHeight();
  double imgWidth  =  pictureData.getImageDimensionInPixels().getWidth();
  double sildeHeight =  slideShow.getPageSize().getHeight();
  double slideWidth  =  slideShow.getPageSize().getWidth();

  //How to calculate the offset above and below the image
  // imgWidth stretched to slideWidth => ratio = slideWidth / imgWidth
  double ratio = slideWidth / imgWidth;
  // sildeHeight% = 100%
  // imgHeight% = (imgHeight * ratio) * 100% / sildeHeight
  double imgHeightPerCent = (imgHeight * ratio) * 100 / sildeHeight;
  // topMiddle% = (100% - imgHeight%) / 2
  // bottomMiddle% = (100% - imgHeight%) / 2
  // topMiddle+1slideHeight% = (100% - imgHeight%) / 2) - 100%
  // bottomMiddle+1slideHeight% = (100% - imgHeight%) / 2 + 100%
  // topMiddle-1slideHeight% = (100% - imgHeight%) / 2) + 100%
  // bottomMiddle-1slideHeight% = (100% - imgHeight%) / 2 - 100%

  // first slide
  XSLFSlide slide = slideShow.createSlide();
  CTBackgroundProperties backgroundProperties = slide.getXmlObject().getCSld().addNewBg().addNewBgPr();
  CTBlipFillProperties blipFillProperties = backgroundProperties.addNewBlipFill();
  CTRelativeRect ctRelativeRect = blipFillProperties.addNewStretch().addNewFillRect();

  // first slide shows 1 slide above middle of long picture
  // measurement unit is thousandth => percent * 1000
  int top = (int)Math.round(((100 - imgHeightPerCent) / 2 + 100) * 1000);
  int bottom = (int)Math.round(((100 - imgHeightPerCent) / 2 -100) * 1000);
  ctRelativeRect.setT(top);
  ctRelativeRect.setB(bottom);

  String idx = slide.addRelation(null, XSLFRelation.IMAGES, pictureData).getRelationship().getId();
  CTBlip blib = blipFillProperties.addNewBlip();
  blib.setEmbed(idx);

  // second slide
  slide = slideShow.createSlide();
  backgroundProperties = slide.getXmlObject().getCSld().addNewBg().addNewBgPr();
  blipFillProperties = backgroundProperties.addNewBlipFill();
  ctRelativeRect = blipFillProperties.addNewStretch().addNewFillRect();

  // second slide shows middle of long picture
  top = (int)Math.round(((100 - imgHeightPerCent) / 2) * 1000);
  bottom = (int)Math.round(((100 - imgHeightPerCent) / 2) * 1000);
  ctRelativeRect.setT(top);
  ctRelativeRect.setB(bottom);

  idx = slide.addRelation(null, XSLFRelation.IMAGES, pictureData).getRelationship().getId();
  blib = blipFillProperties.addNewBlip();
  blib.setEmbed(idx);

  // third slide
  slide = slideShow.createSlide();
  backgroundProperties = slide.getXmlObject().getCSld().addNewBg().addNewBgPr();
  blipFillProperties = backgroundProperties.addNewBlipFill();
  ctRelativeRect = blipFillProperties.addNewStretch().addNewFillRect();

  // third slide shows 1 slide below middle of long picture
  top = (int)Math.round(((100 - imgHeightPerCent) / 2 - 100) * 1000);
  bottom = (int)Math.round(((100 - imgHeightPerCent) / 2 + 100) * 1000);
  ctRelativeRect.setT(top);
  ctRelativeRect.setB(bottom);

  idx = slide.addRelation(null, XSLFRelation.IMAGES, pictureData).getRelationship().getId();
  blib = blipFillProperties.addNewBlip();
  blib.setEmbed(idx);


  FileOutputStream out = new FileOutputStream("CreatePPTXSheetsBackgroundPicture.pptx");
  slideShow.write(out);
  out.close();
 }
}

第二张幻灯片显示长图片的中间,如您想要的效果所述。

提示:

整个效果只能使用PowerPoint查看。 Impress 无法显示该效果。 PowerPoint 2007 可以使用低于 0% 和/或大于 100% 的偏移量显示效果,但无法设置低于 0% 和/或大于 100% 的偏移量。

关于java - 如何使用 apache poi 将背景图像设置为居中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54346189/

相关文章:

javascript - 如果找到图像,则加载图像,否则加载另一个图像

ruby-on-rails - 乘客+ Apache "TraceEnable Off"

java - 连接到 JDBC 时出现 java.lang.ExceptionInInitializerError

java - 字符串与新数据类

java - 如何在 Hibernate 查询和 Session.get() 中启用 MySQL BINARY 运算符

css - 停止将 CSS 'a' 样式应用于链接的图像

image - 如何结束动画? (加工)

java - "error: cannot find symbol"使用 Apache POI

java - 在JSP中导入org.apache.commons时出现问题

php - node.js 与 Apache PHP 一起运行?