Могу ли я получить NaturalSize изображений без их загрузки? - PullRequest
2 голосов
/ 06 мая 2019

Я пытаюсь получить NaturalWidth и NaturalHeight изображения, не загружая его, чтобы ускорить процесс. Есть способ сделать это? Спасибо!

EDIT: Мне сказали поделиться кодом, но я не знаю, чем поделиться.

Вот что я использую, чтобы получить все размеры изображений:

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();
});

Но два кода не работают вместе ...

1 Ответ

1 голос
/ 06 мая 2019

Если у вас есть контроль над сервером, вы можете передать размер изображения в виде заголовков HTTP. В противном случае вы можете только прочитать размер изображения, не загружая его.

Чтение размера изображения

Следующий код является минимальным примером того, как считывать размер (в байтах) изображения, не загружая его. Он прервет любые запросы изображений и затем вместо этого сделает запрос HEAD, чтобы запросить только заголовки файла для чтения заголовка content-length. Имейте в виду, что при этом возвращается только общий размер файла, а не ширина или высота.

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();
})();

Передача размера изображения в качестве заголовка

Если у вас есть контроль над бэкендом / сервером, вы можете передать размер изображения в качестве заголовка и прочитать его с тем же кодом, который был указан ранее. Просто измените заголовок с content-length на заголовки, отправляющие ширину и высоту.

Поскольку вы ничего не сказали о бэкенде, я предполагаю, что это невозможно. Если у вас есть контроль над бэкэндом и вы используете Node.js в качестве бэкэнда, вы можете прочитать этот вопрос о том, как прочитать размер изображения с помощью Node.js .


Больше невозможно без загрузки изображения. В случае, если вы не управляете сервером, но вам необходимо знать свойства naturalHeight и naturalWidth изображения, вам необходимо загрузить изображение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...