前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 操作 Office:POI word之网络图片处理

Java 操作 Office:POI word之网络图片处理

作者头像
程序员架构进阶
发布2021-08-23 13:51:53
1.3K0
发布2021-08-23 13:51:53
举报
文章被收录于专栏:架构进阶架构进阶

系列文章:

Java 操作 Office:POI 之 word 生成

Java 操作 Office:POI 之 word 图片处理

一 前言

在前面两篇,我们已经知道了Java通过POI生成Word表格、表格内插入图片,并在插入前对图片进行标注操作,本篇将再通过一个更贴近真实场景的案例的实现,来了解一下poi在word导出场景的实战应用。

二 需求

还是以word导出作为主体需求,考虑加载网络图片(通常来自内网,外网会考虑先下载到内网环境并保存内网地址,避免耗时过多),并对图片进行标注。这个标注的含义可能是图片某一个区域的标记物,也可能是识别出一些异常情况,通过特殊颜色的区域标识来突出表现。

三 分解实现

3.1 网络图片加载

如果您之前有写下载工具的经验,那么这将会是一个很简单的问题。使用已有的网络工具包会更简化这个过程。

这里假设没有过类似经历,我们一切从零开始。使用Java的java.net包来做实现。

代码语言:javascript
复制
String imageClueUrl = "http://192.168.1.1:8488/file/image/" +
                    "xxx.jpg";

FileOutputStream fos = null;
BufferedInputStream bis = null;
HttpURLConnection httpUrl = null;
URL url = null;
try {
    url = new URL(imageClueUrl);
    httpUrl = (HttpURLConnection) url.openConnection();
    httpUrl.connect();
    bis = new BufferedInputStream(httpUrl.getInputStream());

} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        if (fos != null){
            fos.close();
        }
        if (bis != null){
            bis.close();
        }
        if (httpUrl != null){
            httpUrl.disconnect();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
代码语言:javascript
复制

通过上面代码,我们可以把图片地址读到BufferedInputStream流中。

3.2 图片标注

回顾前面两节内容,既然我们能拿到图片流,那么接下来在图片流中进行处理就好了。考虑在图片中绘制两个区域,是包含关系。一个多边形,一个矩形。矩形在多边形区域内。

代码语言:javascript
复制
XWPFParagraph paragraph = row2.get(1).getParagraphs().get(0);
XWPFRun run = paragraph.createRun();

String imageClueUrl = "http://10.153.106.16:8488/file/image/" +
        "police@MjAyMTA4MDgvMTg3M2I0YmQxNmRkNDMzMjhiZTI4Y2RmMThiZDYwNzg=";

FileOutputStream fos = null;
BufferedInputStream bis = null;
HttpURLConnection httpUrl = null;
URL url = null;
try {
    url = new URL(imageClueUrl);
    httpUrl = (HttpURLConnection) url.openConnection();
    httpUrl.connect();
    bis = new BufferedInputStream(httpUrl.getInputStream());

    BufferedImage image = ImageIO.read(bis);

    double[] detectArea = {0.5147,0.0135,0.9886,0.0136,0.9847,0.9842,0.5083,0.9819};
    BufferedImage bufferedImage = ImageUtil.addPolygon(image, detectArea, Color.blue);

    String alertArea = "0.8390625,0.08981481,0.0734375,0.38055557";
    List<Rectangle> rectangleList = ImageUtil.str2RectangleList(alertArea);
    System.out.println(rectangleList);
    bufferedImage = ImageUtil.addRects(bufferedImage, rectangleList, Color.red);

    InputStream stream1 = ImageUtil.bufferedImageToInputStream(bufferedImage);
    run.addPicture(stream1, XWPFDocument.PICTURE_TYPE_PNG, "Generated",
            Units.toEMU(364), Units.toEMU(256));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        if (fos != null){
            fos.close();
        }
        if (bis != null){
            bis.close();
        }
        if (httpUrl != null){
            httpUrl.disconnect();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
代码语言:javascript
复制

3.3 其他相关方法

3.3.1 矩形区域绘制

绘制矩形区域标注,支持传入颜色参数:

代码语言:javascript
复制
public static BufferedImage addPolygon(BufferedImage image, double[] arr, Color color) throws Exception {
    Graphics2D g = (Graphics2D) image.getGraphics();
    int width = image.getWidth();
    int height = image.getHeight();

    int length = arr.length / 2;
    int[] realPxs = new int[length];
    int[] realPys = new int[length];
    for (int i=0; i < arr.length; i++){
        if (i % 2 == 0){
            realPxs[i / 2] = (int) (width * arr[i]);
        }else {
            realPys[(i - 1) / 2] = (int) (height * arr[i]);
        }
    }

    g.setColor(color);
    g.setStroke(new BasicStroke(5.0f));
    g.drawPolygon(realPxs, realPys, length);
    return image;
}

3.3.2 绘制多边形

代码语言:javascript
复制
public static List<Rectangle> str2RectangleList(String position){
    List<EmdRectangle> rectangleList = new ArrayList<>();
    String[] positions = position.split(";");
    for (String p : positions){
        String[] location = p.split(",");
        Rectangle rectangle = new Rectangle(Double.parseDouble(location[0]),
                Double.parseDouble(location[1]),
                Double.parseDouble(location[2]),
                Double.parseDouble(location[3]));
        rectangleList.add(rectangle);
    }
    return rectangleList;
}
代码语言:javascript
复制

有一点需要注意,这里使用的实体类 Rectangle不是poi包的,而是我们自己定义的。用于解决与包内Rectangle只支持参数为int型的问题。

3.3.3 实体类

代码语言:javascript
复制
import lombok.Data;

@Data
public class Rectangle {
    public double x;
    public double y;
    public double width;
    public double height;

    public Rectangle(double x, double y, double width, double height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }
}
代码语言:javascript
复制

四 总结

至此,对word导出的研究示例,我们暂时告一段落。等后面有更为复杂的真实需求时,欢迎留言进行探讨。我也会在后续进行更新。

使用的技术本身并不复杂,尤其是本系列的示例,都是一些基础内容的拼接。虽然有几个小难点,但只要思路清晰,还是比较容易找到解决方案的。所以,核心还是在如果对问题进行整理、拆解上,选择合适的解决方案,就可以实现我们问题解决方案的完整拼图。

如果需要完整源码,可关注下方公众号留言获取。欢迎进行持续的技术交流,共同成长。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员架构进阶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 前言
  • 二 需求
  • 三 分解实现
    • 3.1 网络图片加载
      • 3.2 图片标注
        • 3.3 其他相关方法
          • 3.3.1 矩形区域绘制
          • 3.3.2 绘制多边形
          • 3.3.3 实体类
      • 四 总结
      相关产品与服务
      图片处理
      图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档