skip to Main Content

For example:

Slide size : 950 x 510

Image size : 500 x 4620

Here is my code

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());

I don’t know how to calculate the offset of the image, can make it centered.
Please give me some advice.

Here is the image:
enter image description here

Here is the effect I want:
enter image description here

2

Answers


  1. 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);
    }
    
    Login or Signup to reply.
  2. The CTRelativeRect is named relative because it’s dimensions are in percentages of slide height and slide width.
    Your long image will be stretched or compressed to those percent dimensions. Also all offsets left, right, top and bottom are in percent of slide height and slide width.

    As of your shown wanted effect, the image shall fill the full slide width. So picture width will be stretched from 500px to 950px. This is a ratio of 950/500. In same ratio the height also will be stretched.

    Knowing this we need calculating the picture dimensions form pixel into percent of slide dimensions. Knowing this we then can calculating the top offset as (100% – picture height in %) / 2. If the same bottom offset is set, then the exact middle of your long picture will be shown in slide background. If the top offset is (100% – picture height in %) / 2) – 100% and bottom offset is (100% – picture height in %) / 2 + 100%, then slide background shows 1 slide height below middle of long picture.

    Additional to this Microsoft always brings it’s own strange measurement units into account. Because of avoiding floating point numbers for percents the measurement unit is thousandth percent here.

    Example:

    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();
     }
    }
    

    The second slide shows the middle of your long picture, as stated as your wanted effect.

    Hint:

    The whole effect can only be viewed using PowerPoint. Impress is not able showing that effect. And PowerPoint 2007 can show the effect using offsets lower than 0% and/or greater than 100% but is not able setting offsets lower than 0% and/or greater than 100%.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search