How to lock aspect ratio of an image in a docx with Apache POI?



is there a way to enable the “lock aspect ratio” option for an image in a docx using Apache POI? I’m adding an image to a run and i’d like to lock its size. Searched in documentation but nothing found.

To be more clear I am referring to the option available inside word, as showed in the image: https://support.content.office.net/en-us/media/a30a8baa-6775-4931-bca6-199fda6afc6e.png

Thanks

Answer

The answer depends on how the picture is applied to the Word document. If this was done via XWPFRun.addPicture, it is an inline picture in the text run. Then the run contains a drawing layer which contains a inline element containing the picture. This inline element then may contain non visual graphic frame properties which may have graphic frame locks which set no change aspect true.

The XML in /word/document.xml looks like:

<w:r>
 <w:drawing>
  <wp:inline ...>
   <wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="true"/></wp:cNvGraphicFramePr>
    <a:graphic>
   ...

Then for the XWPFRun run containing the picture can be set

run.getCTR().getDrawingArray(0).getInlineArray(0).addNewCNvGraphicFramePr().addNewGraphicFrameLocks().setNoChangeAspect(true);

Complete example:

import java.io.*;

import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.Units;

import java.util.List;
import java.util.ArrayList;

import java.net.URL;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Dimension;

public class CreateWordPicturesInTextRuns {

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

  List<String> pictureURLs = new ArrayList<String>();
  pictureURLs.add("https://www.eastcottvets.co.uk/uploads/Animals/gingerkitten.jpg");
  pictureURLs.add("https://www.catster.com/wp-content/uploads/2017/12/A-kitten-meowing.jpg");
  pictureURLs.add("https://www.animalfriends.co.uk/app/uploads/2014/08/06110347/Kitten-small.jpg");
  pictureURLs.add("https://d27ucmmhxk51xv.cloudfront.net/media/english/illustration/kitten.jpg");

  XWPFDocument document= new XWPFDocument();
  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run = paragraph.createRun();
  run.setText("The kitten pictures: ");

  URL url;
  BufferedImage image;
  Dimension dim;
  ByteArrayOutputStream bout;
  ByteArrayInputStream bin;
  for (String pictureURL : pictureURLs) {
   try {
       
    url = new URL(pictureURL);
    image = ImageIO.read(url);
    dim = new Dimension(image.getWidth(), image.getHeight());
    double width = dim.getWidth();
    double height = dim.getHeight();
    double scaling = 1.0;
    if (width > 72*3) scaling = (72*3)/width; //scale width not to be greater than 3 inches

    bout = new ByteArrayOutputStream();
    ImageIO.write(image, "jpeg", bout);
    bout.flush();
    bin = new ByteArrayInputStream(bout.toByteArray());
    run = paragraph.createRun();
    run.addPicture(bin, XWPFDocument.PICTURE_TYPE_JPEG, "kitten", 
     Units.toEMU(width*scaling), Units.toEMU(height*scaling));

    //lock aspect ratio
    run.getCTR().getDrawingArray(0).getInlineArray(0).addNewCNvGraphicFramePr().addNewGraphicFrameLocks().setNoChangeAspect(true);
    
   } catch (Exception ex) {
    ex.printStackTrace();
   }
  }

  FileOutputStream out = new FileOutputStream("CreateWordPicturesInTextRuns.docx");
  document.write(out);
  out.close();
  document.close();

 }
}


Source: stackoverflow