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日志,看调用栈,看看到底是慢在了哪里。