UNPKG

@lewiswright/vitest-plugin-vis

Version:
43 lines (42 loc) 2 kB
import pixelmatch from 'pixelmatch'; import { ssim } from 'ssim.js'; import { convertThresholdUnit } from "./convert_threshold_unit.js"; export function compareImage(img1, img2, output, width, height, options = {}) { const pixelDiff = options.comparisonMethod === 'ssim' ? compareWithSsim(img1, img2, output, width, height, options.diffOptions) : pixelmatch(img1, img2, output, width, height, options.diffOptions); const diffAmount = convertThresholdUnit({ failureThresholdType: options.failureThresholdType ?? 'pixel', width, height }, pixelDiff); return { pass: diffAmount <= (options.failureThreshold ?? 0), diffAmount, }; } /** * @author This code is based on `jest-image-snapshot` implementation. */ function compareWithSsim(img1, img2, output, width, height, diffOptions) { const newImage = { data: img1, width: width, height: height }; const baselineImage = { data: img2, width: width, height: height }; const { ssim_map, mssim } = ssim(newImage, baselineImage, { ssim: 'bezkrovny', ...diffOptions, }); // Converts the SSIM value to different pixels based on image width and height // conforms to how pixelmatch works. const diffPixels = Math.round((1 - mssim) * width * height); const diffRgbaPixels = new DataView(output.buffer, output.byteOffset); for (let ln = 0; ln !== height; ++ln) { for (let pos = 0; pos !== width; ++pos) { const rPos = ln * width + pos; // initial value is transparent. We'll add in the SSIM offset. // red (ff) green (00) blue (00) alpha (00) const diffValue = 0xff000000 + Math.floor(0xff * (1 - ssim_map.data[ssim_map.width * Math.round((ssim_map.height * ln) / height) + Math.round((ssim_map.width * pos) / width)])); diffRgbaPixels.setUint32(rPos * 4, diffValue); } } return diffPixels; }