添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 将图像转为jpeg而是的流数据 ImageIO.write(bufferedImage,"jpeg", baos); byte[] image_bytes = baos.toByteArray();

运行结果:

这样的代码生成一张像素256x256的jpg图像需要消耗时间150毫秒左右,我认为时间还是太慢了,因为我需要大量且频繁的生成这样的图像。这样的代码是否能优化,或者采用什么组件?

* @param slideName 切片名 * @param level 获取指定WSI level图像 * @param row 获取WSI图像X轴坐标 * @param column 获取WSI图像Y轴坐标 * @return * @throws IOException @GetMapping(value = "/getTile/{slideName}/{level}/{row}_{column}.jpg", produces = MediaType.IMAGE_JPEG_VALUE) @Async("wsiImage") public CompletableFuture<byte[]> getTile(@PathVariable String slideName, @PathVariable Integer level, @PathVariable Integer row, @PathVariable Integer column) throws IOException { // 函数执行时间 long begin_time = System.currentTimeMillis(); // 加载WSI图像 String wsiPath = WSIRootPath.getFileRootPath() + slideName; File wsi_file = new File(wsiPath); // 调用OpenSlide组件,操作WSI图像 OpenSlide openSlide = new OpenSlide(wsi_file); // 画图 openSlide.paintRegionOfLevel(graphics, 0, 0, row*256, column*256, TILE_WIDTH, TILE_HEIGHT, level); openSlide.dispose(); // 将图像转成字节流 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(bufferedImage,"jpeg", baos); byte[] image_bytes = baos.toByteArray(); // 释放内存 openSlide.close(); // 函数结束时间 long end_time = System.currentTimeMillis(); log.info("客户端已经请求第"+ (++times) +"次,消耗时间为:" + (end_time-begin_time) + "ms, Tile = "+ level +"_"+row+"_"+column); // 返回图像 return CompletableFuture.completedFuture(image_bytes);

这是完整源码,其中OpenSlide为第三方组件,用于读取金字塔图像的工具,时间上是否有可以优化的空间,这里我已经开启多线程。

* @param slideName 切片名 * @param level 获取指定WSI level图像 * @param row 获取WSI图像X轴坐标 * @param column 获取WSI图像Y轴坐标 * @return * @throws IOException @GetMapping(value = "/getTile/{slideName}/{level}/{row}_{column}.jpg", produces = MediaType.IMAGE_JPEG_VALUE) public void getTile(@PathVariable String slideName, @PathVariable Integer level, @PathVariable Integer row, @PathVariable Integer column, HttpServletResponse response) throws IOException { // 函数执行时间 long begin_time = System.currentTimeMillis(); // 加载WSI图像 String wsiPath = WSIRootPath.getFileRootPath() + slideName; File wsi_file = new File(wsiPath); // 调用OpenSlide组件,操作WSI图像 OpenSlide openSlide = new OpenSlide(wsi_file); // 画图 openSlide.paintRegionOfLevel(graphics, 0, 0, row*256, column*256, TILE_WIDTH, TILE_HEIGHT, level); openSlide.dispose(); // 将图像转成字节流 // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 把图片IO到客户端 response.setContentType(MediaType.IMAGE_JPEG_VALUE); ImageIO.write(bufferedImage,"jpeg", response.getOutputStream()); // byte[] image_bytes = baos.toByteArray(); // // 释放内存 // openSlide.close(); // // 函数结束时间 // long end_time = System.currentTimeMillis(); // log.info("客户端已经请求第"+ (++times) +"次,消耗时间为:" + (end_time-begin_time) + "ms, Tile = "+ level +"_"+row+"_"+column); // // 返回图像

核心就是:

  • 不要用异步,这个没多大效果。
  • ImageIO 可以直接把图片数据响应到客户端,避免多余的复制。

    如果还是慢,那么你要看DEBUG日志,看调用栈,看看到底是慢在了哪里。