我正在构建一个 Electron 应用程序(Chrome + Node.js),其目标是显示指定文件夹的所有图像。
这是一个应用程序,因此所有图像都已在磁盘上,无需下载任何内容。
问题:
我需要它来将所有图像显示为 64x64
缩略图,但因为它们被加载为 <img>
元素,原始图像被加载到 RAM 中,并且只有在 CSS 将它们“调整大小”到 width: 64px; height: 64px
之后。 ,但事实并非如此,它仍然在 RAM 中保存原始图像,因此显示 300 个图像(1mb-20mb)需要约 3.5 GB 的 RAM。
问题:
所以,我想知道是否有更简单的方法来获得 64x64
图像的缩略图并在网页上显示该图像而不是原始图像?
是否有可能在显示图像之前(即在将图像加载到 RAM 之前)让浏览器缩小尺寸(实际上将图像大小调整为 64x64)?
尝试过:
我尝试使用<canvas>
而不是<img>
但它使应用程序在滚动时变得滞后,因为它的计算量相当大(~0.1ms/图像)。我想将其发送给网络 worker ,但无法做到。
//我在那里使用 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
并将它们保存到磁盘。它很慢,但我可以使用网络 worker 将此作业发送到另一个核心
最佳答案
不加载原始图像的唯一方法是将调整大小的缩略图也保存到磁盘并加载它。
这取决于这些图像的来源。
如果它们是由您创建并与应用程序一起预打包的,您可以自行调整大小并打包每个图像的两个版本(例如 myimage_500x500.png
和 myimage_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处理的路由请求图像,然后从磁盘加载图像并动态调整大小。
一旦请求完成,大图像将被垃圾收集,并且前端仅显示小缩略图。
关于javascript - 在显示图像并将原始图像加载到 RAM 之前是否可以缩小(实际上调整大小)图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51423850/