How to set image size is dynamically in poi word run.addPicture()?

我的未来我决定 提交于 2020-01-02 07:05:57

问题


 XWPFDocument doc= new XWPFDocument();
 InputStream a = someMethod(underConditions(inputimage));
 paragraph.createRun().addPicture(a, Document.PICTURE_TYPE_PNG, "", Units.toEMU(20), Units.toEMU(20));
 a.close();
 doc.write(new FileOutputStream("CreateWordHeaderFooter.docx"));
 doc.close();

This is simple code for add a image in poi word. But InputStream a is different under different conditions. If inputimage is small Units.toEMU(20), Units.toEMU(20) is to big, and if inputimage is big Units.toEMU(20), Units.toEMU(20) is too small. In this conditions images are distorted. So my question is how to set dynamic image size based on different image. Thanks.


回答1:


So we need determining the preferred dimensions of the images from their files. There are already much discussions on how to do that. Search keywords: java get dimension from image file. Simplest possibility is using ImageIO to read BufferedImage from the file which then has widthand height properties.

Example:

import java.io.*;

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

import org.apache.poi.util.Units;

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

public class CreateWordImagesPreferredSize {

 static Dimension getImageDimension(File imgFile) throws IOException {
  BufferedImage img = ImageIO.read(imgFile);
  return new Dimension(img.getWidth(), img.getHeight());
 }

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

  XWPFDocument doc= new XWPFDocument();

  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run = paragraph.createRun();  
  run.setText("The Images:");

  String[] images = new String[]{"Koala.png", "Scannen.jpg", "Winter.bmp"};

  for (int i = 0 ; i < images.length; i++) {

   paragraph = doc.createParagraph();
   run = paragraph.createRun();

   File imgFile = new File(images[i]);
   Dimension dim = getImageDimension(imgFile);
   System.out.println(dim);

   double width = dim.getWidth();
   double height = dim.getHeight();

   double scaling = 1.0;
   if (width > 72*6) scaling = (72*6)/width; //scale width not to be greater than 6 inches

   InputStream in = new FileInputStream(imgFile);
   paragraph.createRun().addPicture(in, Document.PICTURE_TYPE_PNG, images[i], 
    Units.toEMU(width*scaling), Units.toEMU(height*scaling));
   in.close();

  }

  doc.write(new FileOutputStream("CreateWordImagesPreferredSize.docx"));
  doc.close();

 }
}

Note: I do scaling the image to be not greater than 6 inches width if its original size is greater. So it will fit into one page width. Smaller images will not be scaled.


Edit:

As from the comments, if you cannot using File but must using InputStream, then you need to know, that BufferedImage img = ImageIO.read(imgStream); of course reads from the stream. So the stream will be at its end after that. So .addPicture(imgStream,...) will need a newly opened stream then.

Example:

import java.io.*;

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

import org.apache.poi.util.Units;

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

public class CreateWordImagesPreferredSizeStream {

 static InputStream getInputStream(String filename) throws Exception {
  return new FileInputStream(filename);
 }

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

  XWPFDocument doc= new XWPFDocument();

  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run = paragraph.createRun();  
  run.setText("The Images:");

  String[] images = new String[]{"Koala.png", "Scannen.jpg", "Winter.bmp"};

  for (int i = 0 ; i < images.length; i++) {

   paragraph = doc.createParagraph();
   run = paragraph.createRun();

   InputStream imgStream = getInputStream(images[i]);

   BufferedImage img = ImageIO.read(imgStream);
   double w = img.getWidth();
   double h = img.getHeight();
   imgStream.close();

   System.out.println(w);
   System.out.println(h);

   double scaling = 1.0;
   if (w > 72*6) scaling = (72*6)/w; //scale width not to be greater than 6 inches

   imgStream = getInputStream(images[i]);

   paragraph.createRun().addPicture(imgStream, Document.PICTURE_TYPE_PNG, images[i], 
    Units.toEMU(w*scaling), Units.toEMU(h*scaling));
   imgStream.close();

  }

  doc.write(new FileOutputStream("CreateWordImagesPreferredSize.docx"));
  doc.close();

 }
}


来源:https://stackoverflow.com/questions/43511968/how-to-set-image-size-is-dynamically-in-poi-word-run-addpicture

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!