在显示图像并将原始图像加载到RAM之前是否可以缩小图像(实际调整大小)?

时间:2018-07-19 13:24:01

标签: javascript html node.js browser browser-cache

我正在构建一个电子应用程序(Chrome + Node.js),其目的是显示指定文件夹的所有图像。

这是一个应用程序,因此所有图像都已经在磁盘上,无需下载任何内容。

问题:

我需要它以64x64缩略图的形式显示所有图像,但是由于它们是作为<img>元素加载的,因此原始图像将被加载到RAM中,并且只有在CSS“调整”它们的大小之后到width: 64px; height: 64px,但这不是真的,它仍将原始图像保存在RAM中,因此显示300张图像(1mb-20mb)大约需要3.5 GB RAM。

问题:

因此,我想知道是否有更简单的方法来获取图像的64x64缩略图并在网页上显示而不是原始?

是否有可能使浏览器在显示图像之前缩小图像(实际上将图像尺寸调整为64x64)(意味着将它们加载到RAM之前)?

尝试:

我尝试使用<canvas>而不是<img>,但是它使应用程序在滚动时显得迟钝,因为它的计算量很大(〜0.1ms /图像)。我想将其发送给网络工作者,但无法执行。

//我在这里使用vue.js

// THIS TAG IS INSIDE A V-FOR LOOP SO A CANVAS TAG IS CREATED FOR EACH ITEM IN THE LIST
<canvas :id="'item-' + props.index"> 
  {{drawThumbnails(props.item.path, props.index)}} 
</canvas> 

drawThumbnails (path, canvasId) {
  console.time('draw time')
  var image = new Image(); 
  image.onload = function() {
    var canvas = document.getElementById(canvasId);
    canvas.width = 64;
    canvas.height = 64;
    canvas.getContext("2d").drawImage(image, 0, 0, 64, 64);
  }
  image.src = path
  console.timeEnd('draw time')
}

我认为可以做到的另一种方法是使用64x64将图像调整为jimp并将其保存到磁盘。速度很慢,但是我可以使用网络工作者将此工作发送到另一个核心

1 个答案:

答案 0 :(得分:1)

不加载原始图像的唯一方法是将调整大小的缩略图也保存到磁盘上,然后加载。

这取决于这些图像的来源。

如果它们是由您创建并与应用程序预先打包的,则可以自行调整大小并打包每个图像的两个版本(例如myimage_500x500.pngmyimage_64x64.png)。

如果图像是由该应用程序创建的,即该应用程序正在用户的PC上运行,并从某个来源获取图像数据并将其写入磁盘,那么它还可以创建缩略图并保存。一个不错的实用工具是sharp

const sharp = require('sharp');
const fs = require('fs');

const imageBuffer = getImage() // Data from some source

fs.writeFile('image.png', imageBuffer, (err) => {
  if (err) return callback(err)

  sharp(originalImageBuffer)
    .resize(64, 64)
    .toFile('image_64x64.png', callback);
});

如果图像位于用户的硬盘驱动器上,但尚未被应用程序放置在该位置(即,您仅访问现有文件夹),那么您还需要进行上述调整大小,但是会被其他事件触发。例如。首次显示图像时或您定期检查是否有新图像时。


还有一种方法不必在磁盘上存储缩略图,也不必在显示大图时保持加载。 如果您添加了express应用或类似的应用,则可以让<img>标签从express处理的路由中请求其图像,然后再从磁盘加载图像并快速进行大小调整。

请求完成后,大图像将被垃圾收集,并且前端仅显示小缩略图。