我可以在不加载图像的情况下获取图像的 NaturalSize 吗?
Can I get the NaturalSize of images without loading them?
我试图在不加载图像的情况下获取图像的 NaturalWidth 和 NaturalHeight,以加快处理速度。
有没有办法做到这一点?谢谢!
编辑:
我被告知要分享一些代码,但我真的不知道该分享什么。
这是我用来获取所有尺寸图像的方法:
const images_datas = await this.page.$$eval('img', imgs => {
var images_data = []
var empty_images = 0
imgs.forEach(img => {
if(img.naturalWidth*img.naturalHeight == 0 || ( img.naturalHeight == 1 && img.naturalWidth == 1)){
empty_images++
} else {
images_data.push({'url': img.src, 'width': img.naturalWidth, 'height' : img.naturalHeight, 'alt' : img.alt})
}
});
return {'images_data': images_data, 'nb_empty_images': empty_images}
} );
还有我用来阻止图片加载的代码。
await page.setRequestInterception(true);
page.on('request', request => {
if (request.resourceType() === 'image')
request.abort();
else
request.continue();
});
但是这两个代码不能一起使用...
如果您可以控制服务器,则可以将图像大小作为 HTTP headers 传递。否则只能读取图片大小而不能加载。
读取图像的大小
以下代码是关于如何在不下载图像的情况下读取图像大小(以字节为单位)的最小示例。它将中止任何图像请求,然后改为执行 HEAD
请求以仅请求文件的 header 来读取 content-length
header。请注意,这只是 returns 文件总大小,而不是宽度或高度。
const puppeteer = require('puppeteer');
const fetch = require('node-fetch');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', interceptedRequest => {
if (interceptedRequest.resourceType() === 'image') {
interceptedRequest.abort();
const response = await fetch(interceptedRequest.url(), {
method: 'HEAD'
});
if (response.ok) {
const sizeOfImage = response.headers.get('content-length');
// handle image size
} else {
// something went wrong...
}
} else {
interceptedRequest.continue();
}
});
await page.goto('...');
await browser.close();
})();
将图像的大小传递为 header
如果您可以控制 backend/server,您可以将图像的大小作为 header 传递,然后使用与之前给出的代码相同的代码读取它。只需将 header 从 content-length
更改为发送宽度和高度的 headers。
由于您没有提及后端,我假设这是不可能的。如果您可以控制后端并且使用 Node.js 作为后端,您可能需要阅读有关如何 read the image size with Node.js.
的问题
如果不加载图像,则无法进行更多操作。如果您不控制服务器,但需要知道图像的 naturalHeight
和 naturalWidth
属性,则必须加载图像。
我试图在不加载图像的情况下获取图像的 NaturalWidth 和 NaturalHeight,以加快处理速度。 有没有办法做到这一点?谢谢!
编辑: 我被告知要分享一些代码,但我真的不知道该分享什么。
这是我用来获取所有尺寸图像的方法:
const images_datas = await this.page.$$eval('img', imgs => {
var images_data = []
var empty_images = 0
imgs.forEach(img => {
if(img.naturalWidth*img.naturalHeight == 0 || ( img.naturalHeight == 1 && img.naturalWidth == 1)){
empty_images++
} else {
images_data.push({'url': img.src, 'width': img.naturalWidth, 'height' : img.naturalHeight, 'alt' : img.alt})
}
});
return {'images_data': images_data, 'nb_empty_images': empty_images}
} );
还有我用来阻止图片加载的代码。
await page.setRequestInterception(true);
page.on('request', request => {
if (request.resourceType() === 'image')
request.abort();
else
request.continue();
});
但是这两个代码不能一起使用...
如果您可以控制服务器,则可以将图像大小作为 HTTP headers 传递。否则只能读取图片大小而不能加载。
读取图像的大小
以下代码是关于如何在不下载图像的情况下读取图像大小(以字节为单位)的最小示例。它将中止任何图像请求,然后改为执行 HEAD
请求以仅请求文件的 header 来读取 content-length
header。请注意,这只是 returns 文件总大小,而不是宽度或高度。
const puppeteer = require('puppeteer');
const fetch = require('node-fetch');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', interceptedRequest => {
if (interceptedRequest.resourceType() === 'image') {
interceptedRequest.abort();
const response = await fetch(interceptedRequest.url(), {
method: 'HEAD'
});
if (response.ok) {
const sizeOfImage = response.headers.get('content-length');
// handle image size
} else {
// something went wrong...
}
} else {
interceptedRequest.continue();
}
});
await page.goto('...');
await browser.close();
})();
将图像的大小传递为 header
如果您可以控制 backend/server,您可以将图像的大小作为 header 传递,然后使用与之前给出的代码相同的代码读取它。只需将 header 从 content-length
更改为发送宽度和高度的 headers。
由于您没有提及后端,我假设这是不可能的。如果您可以控制后端并且使用 Node.js 作为后端,您可能需要阅读有关如何 read the image size with Node.js.
的问题如果不加载图像,则无法进行更多操作。如果您不控制服务器,但需要知道图像的 naturalHeight
和 naturalWidth
属性,则必须加载图像。