如何在poi词run.addPicture()中动态设置图像大小?

Suc*_*ucy 3 apache-poi

 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();
Run Code Online (Sandbox Code Playgroud)

这是用于在poi word中添加图像的简单代码。但是InputStream a在不同条件下是不同的。如果inputimage小Units.toEMU(20),则Units.toEMU(20)为大;如果inputimage大Units.toEMU(20),则Units.toEMU(20)太小。在这种情况下,图像会失真。所以我的问题是如何根据不同的图像设置动态图像尺寸。谢谢。

Axe*_*ter 5

因此,我们需要从文件中确定图像的首选尺寸。关于如何做到这一点已经有很多讨论。搜索关键字:java get dimension from image file。最简单的可能性是使用ImageIO来读取BufferedImage具有widthheight属性的文件。

例:

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

 }
}
Run Code Online (Sandbox Code Playgroud)

注意:如果原始尺寸较大,我会将图像缩放到不大于6英寸的宽度。因此,它将适合一页宽度。较小的图像将不会缩放。


编辑:

从注释中可以看出,如果您不能使用,File但必须使用InputStream,那么您需要知道,这BufferedImage img = ImageIO.read(imgStream);当然是从流中读取的。因此,流将在此之后结束。所以.addPicture(imgStream,...)需要一个新打开的流。

例:

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

 }
}
Run Code Online (Sandbox Code Playgroud)