您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
temporary lib: pixelmatch@5.2.0
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/401377/970885/pixelmatch.js
- (function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory();
- else if(typeof define === 'function' && define.amd)
- define([], factory);
- else if(typeof exports === 'object')
- exports["pixelmatch"] = factory();
- else
- root["pixelmatch"] = factory();
- })(self, function() {
- return /******/ (() => { // webpackBootstrap
- /******/ var __webpack_modules__ = ({
- /***/ 148:
- /***/ ((module) => {
- "use strict";
- module.exports = pixelmatch;
- const defaultOptions = {
- threshold: 0.1, // matching threshold (0 to 1); smaller is more sensitive
- includeAA: false, // whether to skip anti-aliasing detection
- alpha: 0.1, // opacity of original image in diff ouput
- aaColor: [255, 255, 0], // color of anti-aliased pixels in diff output
- diffColor: [255, 0, 0], // color of different pixels in diff output
- diffColorAlt: null, // whether to detect dark on light differences between img1 and img2 and set an alternative color to differentiate between the two
- diffMask: false // draw the diff over a transparent background (a mask)
- };
- function pixelmatch(img1, img2, output, width, height, options) {
- if (!isPixelData(img1) || !isPixelData(img2) || (output && !isPixelData(output)))
- throw new Error('Image data: Uint8Array, Uint8ClampedArray or Buffer expected.');
- if (img1.length !== img2.length || (output && output.length !== img1.length))
- throw new Error('Image sizes do not match.');
- if (img1.length !== width * height * 4) throw new Error('Image data size does not match width/height.');
- options = Object.assign({}, defaultOptions, options);
- // check if images are identical
- const len = width * height;
- const a32 = new Uint32Array(img1.buffer, img1.byteOffset, len);
- const b32 = new Uint32Array(img2.buffer, img2.byteOffset, len);
- let identical = true;
- for (let i = 0; i < len; i++) {
- if (a32[i] !== b32[i]) { identical = false; break; }
- }
- if (identical) { // fast path if identical
- if (output && !options.diffMask) {
- for (let i = 0; i < len; i++) drawGrayPixel(img1, 4 * i, options.alpha, output);
- }
- return 0;
- }
- // maximum acceptable square distance between two colors;
- // 35215 is the maximum possible value for the YIQ difference metric
- const maxDelta = 35215 * options.threshold * options.threshold;
- let diff = 0;
- // compare each pixel of one image against the other one
- for (let y = 0; y < height; y++) {
- for (let x = 0; x < width; x++) {
- const pos = (y * width + x) * 4;
- // squared YUV distance between colors at this pixel position, negative if the img2 pixel is darker
- const delta = colorDelta(img1, img2, pos, pos);
- // the color difference is above the threshold
- if (Math.abs(delta) > maxDelta) {
- // check it's a real rendering difference or just anti-aliasing
- if (!options.includeAA && (antialiased(img1, x, y, width, height, img2) ||
- antialiased(img2, x, y, width, height, img1))) {
- // one of the pixels is anti-aliasing; draw as yellow and do not count as difference
- // note that we do not include such pixels in a mask
- if (output && !options.diffMask) drawPixel(output, pos, ...options.aaColor);
- } else {
- // found substantial difference not caused by anti-aliasing; draw it as such
- if (output) {
- drawPixel(output, pos, ...(delta < 0 && options.diffColorAlt || options.diffColor));
- }
- diff++;
- }
- } else if (output) {
- // pixels are similar; draw background as grayscale image blended with white
- if (!options.diffMask) drawGrayPixel(img1, pos, options.alpha, output);
- }
- }
- }
- // return the number of different pixels
- return diff;
- }
- function isPixelData(arr) {
- // work around instanceof Uint8Array not working properly in some Jest environments
- return ArrayBuffer.isView(arr) && arr.constructor.BYTES_PER_ELEMENT === 1;
- }
- // check if a pixel is likely a part of anti-aliasing;
- // based on "Anti-aliased Pixel and Intensity Slope Detector" paper by V. Vysniauskas, 2009
- function antialiased(img, x1, y1, width, height, img2) {
- const x0 = Math.max(x1 - 1, 0);
- const y0 = Math.max(y1 - 1, 0);
- const x2 = Math.min(x1 + 1, width - 1);
- const y2 = Math.min(y1 + 1, height - 1);
- const pos = (y1 * width + x1) * 4;
- let zeroes = x1 === x0 || x1 === x2 || y1 === y0 || y1 === y2 ? 1 : 0;
- let min = 0;
- let max = 0;
- let minX, minY, maxX, maxY;
- // go through 8 adjacent pixels
- for (let x = x0; x <= x2; x++) {
- for (let y = y0; y <= y2; y++) {
- if (x === x1 && y === y1) continue;
- // brightness delta between the center pixel and adjacent one
- const delta = colorDelta(img, img, pos, (y * width + x) * 4, true);
- // count the number of equal, darker and brighter adjacent pixels
- if (delta === 0) {
- zeroes++;
- // if found more than 2 equal siblings, it's definitely not anti-aliasing
- if (zeroes > 2) return false;
- // remember the darkest pixel
- } else if (delta < min) {
- min = delta;
- minX = x;
- minY = y;
- // remember the brightest pixel
- } else if (delta > max) {
- max = delta;
- maxX = x;
- maxY = y;
- }
- }
- }
- // if there are no both darker and brighter pixels among siblings, it's not anti-aliasing
- if (min === 0 || max === 0) return false;
- // if either the darkest or the brightest pixel has 3+ equal siblings in both images
- // (definitely not anti-aliased), this pixel is anti-aliased
- return (hasManySiblings(img, minX, minY, width, height) && hasManySiblings(img2, minX, minY, width, height)) ||
- (hasManySiblings(img, maxX, maxY, width, height) && hasManySiblings(img2, maxX, maxY, width, height));
- }
- // check if a pixel has 3+ adjacent pixels of the same color.
- function hasManySiblings(img, x1, y1, width, height) {
- const x0 = Math.max(x1 - 1, 0);
- const y0 = Math.max(y1 - 1, 0);
- const x2 = Math.min(x1 + 1, width - 1);
- const y2 = Math.min(y1 + 1, height - 1);
- const pos = (y1 * width + x1) * 4;
- let zeroes = x1 === x0 || x1 === x2 || y1 === y0 || y1 === y2 ? 1 : 0;
- // go through 8 adjacent pixels
- for (let x = x0; x <= x2; x++) {
- for (let y = y0; y <= y2; y++) {
- if (x === x1 && y === y1) continue;
- const pos2 = (y * width + x) * 4;
- if (img[pos] === img[pos2] &&
- img[pos + 1] === img[pos2 + 1] &&
- img[pos + 2] === img[pos2 + 2] &&
- img[pos + 3] === img[pos2 + 3]) zeroes++;
- if (zeroes > 2) return true;
- }
- }
- return false;
- }
- // calculate color difference according to the paper "Measuring perceived color difference
- // using YIQ NTSC transmission color space in mobile applications" by Y. Kotsarenko and F. Ramos
- function colorDelta(img1, img2, k, m, yOnly) {
- let r1 = img1[k + 0];
- let g1 = img1[k + 1];
- let b1 = img1[k + 2];
- let a1 = img1[k + 3];
- let r2 = img2[m + 0];
- let g2 = img2[m + 1];
- let b2 = img2[m + 2];
- let a2 = img2[m + 3];
- if (a1 === a2 && r1 === r2 && g1 === g2 && b1 === b2) return 0;
- if (a1 < 255) {
- a1 /= 255;
- r1 = blend(r1, a1);
- g1 = blend(g1, a1);
- b1 = blend(b1, a1);
- }
- if (a2 < 255) {
- a2 /= 255;
- r2 = blend(r2, a2);
- g2 = blend(g2, a2);
- b2 = blend(b2, a2);
- }
- const y1 = rgb2y(r1, g1, b1);
- const y2 = rgb2y(r2, g2, b2);
- const y = y1 - y2;
- if (yOnly) return y; // brightness difference only
- const i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2);
- const q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2);
- const delta = 0.5053 * y * y + 0.299 * i * i + 0.1957 * q * q;
- // encode whether the pixel lightens or darkens in the sign
- return y1 > y2 ? -delta : delta;
- }
- function rgb2y(r, g, b) { return r * 0.29889531 + g * 0.58662247 + b * 0.11448223; }
- function rgb2i(r, g, b) { return r * 0.59597799 - g * 0.27417610 - b * 0.32180189; }
- function rgb2q(r, g, b) { return r * 0.21147017 - g * 0.52261711 + b * 0.31114694; }
- // blend semi-transparent color with white
- function blend(c, a) {
- return 255 + (c - 255) * a;
- }
- function drawPixel(output, pos, r, g, b) {
- output[pos + 0] = r;
- output[pos + 1] = g;
- output[pos + 2] = b;
- output[pos + 3] = 255;
- }
- function drawGrayPixel(img, i, alpha, output) {
- const r = img[i + 0];
- const g = img[i + 1];
- const b = img[i + 2];
- const val = blend(rgb2y(r, g, b), alpha * img[i + 3] / 255);
- drawPixel(output, i, val, val, val);
- }
- /***/ }),
- /***/ 138:
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
- const pixelmatch = __webpack_require__(148);
- module.exports = pixelmatch;
- /***/ })
- /******/ });
- /************************************************************************/
- /******/ // The module cache
- /******/ var __webpack_module_cache__ = {};
- /******/
- /******/ // The require function
- /******/ function __webpack_require__(moduleId) {
- /******/ // Check if module is in cache
- /******/ var cachedModule = __webpack_module_cache__[moduleId];
- /******/ if (cachedModule !== undefined) {
- /******/ return cachedModule.exports;
- /******/ }
- /******/ // Create a new module (and put it into the cache)
- /******/ var module = __webpack_module_cache__[moduleId] = {
- /******/ // no module.id needed
- /******/ // no module.loaded needed
- /******/ exports: {}
- /******/ };
- /******/
- /******/ // Execute the module function
- /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
- /******/
- /******/ // Return the exports of the module
- /******/ return module.exports;
- /******/ }
- /******/
- /************************************************************************/
- /******/
- /******/ // startup
- /******/ // Load entry module and return exports
- /******/ // This entry module is referenced by other modules so it can't be inlined
- /******/ var __webpack_exports__ = __webpack_require__(138);
- /******/
- /******/ return __webpack_exports__;
- /******/ })()
- ;
- });
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址