Как установить фоновое изображение по центру с помощью apache poi - PullRequest
0 голосов
/ 24 января 2019

Например:

Размер слайда: 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());

Я не знаю, как рассчитать смещение изображения, могу сделать его по центру. Пожалуйста, дайте мне несколько советов.

Вот изображение: введите описание изображения здесь

Вот эффект, который я хочу: введите описание изображения здесь

Ответы [ 2 ]

0 голосов
/ 24 января 2019

CTRelativeRect называется относительным, потому что его размеры указаны в процентах от высоты слайда и ширины слайда.Ваше длинное изображение будет растянуто или сжато до тех процентов размеров.Также все смещения слева, справа, сверху и снизу указаны в процентах от высоты слайда и ширины слайда.

По вашему желаемому эффекту изображение должно заполнить всю ширину слайда.Таким образом, ширина изображения будет увеличена с 500 до 950 пикселей.Это соотношение 950/500.В том же соотношении высота также будет растянута.

Зная это, нам нужно вычислить размеры изображения в пикселях в процентах от размеров слайда.Зная это, мы затем можем рассчитать верхнее смещение как (100% - высота изображения в%) / 2. Если установлено то же самое нижнее смещение, то точная середина вашей длинной картинки будет показана на фоне слайда.Если верхнее смещение составляет (100% - высота изображения в%) / 2) - 100%, а нижнее смещение составляет (100% - высота изображения в%) / 2 + 100%, то фон слайда показывает 1 высоту слайда ниже середины длиныpicture.

Дополнительно к этому Microsoft всегда учитывает свои странные единицы измерения.Из-за исключения чисел с плавающей запятой для процентов единица измерения здесь составляет тысячные проценты.

Пример:

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%.

0 голосов
/ 24 января 2019
if (pptHeight - imgHeight < 0) {
    //How to calculate the offset above and below the image
    //instead of double heightOffset = (pptHeight - imgHeight) / 2 
    double heightOffset = (imgHeight - pptHeight) / 2
    ctRelativeRect.setT(heightOffset);
    ctRelativeRect.setB(heightOffset);
}else if(pptWidth - imgWidth < 0) {
    double widthOffset = (pptWidth - imgWidth ) / 2
    ctRelativeRect.setR(widthOffset);
    ctRelativeRect.setL(widthOffset);
}
...