in src/reporters/json.ts [289:342]
export async function getScreenshotBlocks(screenshot: Buffer) {
const { width, height } = await sharp(screenshot).metadata();
/**
* Chop the screenshot image (1280*720) which is the default
* viewport size in to 64 equal blocks for a given image
* which can be acheived by keeping the division to 8
*
* Changing division to 16 would yield us 256 smaller blocks, but it is not
* optimal for caching in the ES and proved out to be bad, so we stick to 8
*/
const divisions = 8;
const blockWidth = Math.floor(width / divisions);
const blockHeight = Math.floor(height / divisions);
const reference: ScreenshotReference = {
width,
height,
blocks: [],
};
const blocks: Array<ScreenshotBlob> = [];
for (let row = 0; row < divisions; row++) {
const top = row * blockHeight;
for (let col = 0; col < divisions; col++) {
const left = col * blockWidth;
// We create a new sharp instance for each block to avoid
// running in to extraction/orientation issues
const buf = await sharp(screenshot, { sequentialRead: true })
.extract({ top, left, width: blockWidth, height: blockHeight })
.jpeg()
.toBuffer();
const hash = createHash('sha1').update(buf).digest('hex');
blocks.push({
blob: buf.toString('base64'),
id: hash,
});
/**
* We dont write the width, height of individual blocks on the
* reference as we use similar sized blocks for each extraction,
* we would need to send the width and height here if we decide to
* go with dynamic block extraction.
*/
reference.blocks.push({
hash,
top,
left,
width: blockWidth,
height: blockHeight,
});
}
}
return { blocks, reference, blob_mime: 'image/jpeg' };
}