mirror of
https://github.com/cnwhy/QRCode-decode.git
synced 2026-08-12 20:31:40 +08:00
107 lines
4.2 KiB
JavaScript
107 lines
4.2 KiB
JavaScript
// 综合回归测试:标准图 + 特殊图 + 构造场景(策略链各层)
|
||
// 用法:node test/all_regression.js
|
||
var server = require('../server');
|
||
var imgDecode = require('../src/imageDecode');
|
||
var qrDecode = require('../src/QRDecode');
|
||
var fs = require('fs');
|
||
var path = require('path');
|
||
|
||
var passCount = 0;
|
||
var failCount = 0;
|
||
|
||
function check(label, actual, expected) {
|
||
if (actual === expected) {
|
||
passCount++;
|
||
console.log('PASS ' + label + ' => ' + actual);
|
||
} else {
|
||
failCount++;
|
||
console.log('FAIL ' + label + ' => ' + actual + '(期望 ' + expected + ')');
|
||
}
|
||
}
|
||
|
||
// ---------- 文件用例:标准图 + 特殊图 ----------
|
||
var fileCases = [
|
||
{ path: './img/16.bmp', label: 'bmp16', expect: '12345' },
|
||
{ path: './img/24.bmp', label: 'bmp24', expect: '12345' },
|
||
{ path: './img/32.bmp', label: 'bmp32', expect: '12345' },
|
||
{ path: './img/lx.jpg', label: 'jpg_lx', expect: '12345' },
|
||
{ path: './img/yh.jpg', label: 'jpg_yh', expect: '12345' },
|
||
{ path: './img/8.png', label: 'png8', expect: '12345' },
|
||
{ path: './img/24.png', label: 'png24', expect: '12345' },
|
||
{ path: './img/jt.gif', label: 'gif_jt', expect: '12345' },
|
||
{ path: './img/dt.gif', label: 'gif_dt', expect: '12345' },
|
||
{ path: './img/otsu.png', label: 'otsu.png 渐变光照', expect: '中国人' },
|
||
{ path: './img/o1.png', label: 'o1.png 透明背景美化码', expect: '中国人' },
|
||
{ path: './img/o2.png', label: 'o2.png 深色背景美化码', expect: '中国人' },
|
||
{ path: './img/o3.png', label: 'o3.png 低对比度图', expect: 'https://mpl.qzz.io/' }
|
||
];
|
||
|
||
// ---------- 构造场景用例:验证策略链各层 ----------
|
||
// 基于 8.png 构造,覆盖:Otsu / 反转 / 反转+Otsu / 数据未污染
|
||
var img8 = (function () {
|
||
var buffer = fs.readFileSync(path.join(__dirname, './img/8.png'));
|
||
var imageData = imgDecode.png(buffer);
|
||
if (Array.isArray(imageData)) imageData = imageData[0];
|
||
return imageData;
|
||
})();
|
||
|
||
var builtCases = [];
|
||
|
||
// 暗化图:RGB × 0.5 -> 需要 Otsu 策略
|
||
(function () {
|
||
var data = new Uint8ClampedArray(img8.data.length);
|
||
for (var i = 0; i < img8.data.length; i += 4) {
|
||
data[i] = img8.data[i] * 0.5 | 0;
|
||
data[i + 1] = img8.data[i + 1] * 0.5 | 0;
|
||
data[i + 2] = img8.data[i + 2] * 0.5 | 0;
|
||
data[i + 3] = img8.data[i + 3];
|
||
}
|
||
builtCases.push({ img: { data: data, width: img8.width, height: img8.height }, label: '暗化图(Otsu)', expect: '12345' });
|
||
})();
|
||
|
||
// 反色码:黑底白码 -> 需要反转策略
|
||
(function () {
|
||
var data = new Uint8ClampedArray(img8.data.length);
|
||
for (var i = 0; i < img8.data.length; i += 4) {
|
||
var gray = (img8.data[i] * 33.33 + img8.data[i + 1] * 33.33 + img8.data[i + 2] * 33.33) / 100;
|
||
var v = gray <= 153 ? 255 : 0;
|
||
data[i] = v; data[i + 1] = v; data[i + 2] = v; data[i + 3] = 255;
|
||
}
|
||
builtCases.push({ img: { data: data, width: img8.width, height: img8.height }, label: '反色码(反转)', expect: '12345' });
|
||
})();
|
||
|
||
// 暗反色码:黑底灰模块 -> 需要反转+Otsu 策略
|
||
(function () {
|
||
var data = new Uint8ClampedArray(img8.data.length);
|
||
for (var i = 0; i < img8.data.length; i += 4) {
|
||
var gray = (img8.data[i] * 33.33 + img8.data[i + 1] * 33.33 + img8.data[i + 2] * 33.33) / 100;
|
||
var v = gray <= 153 ? 95 : 8;
|
||
data[i] = v; data[i + 1] = v; data[i + 2] = v; data[i + 3] = 255;
|
||
}
|
||
builtCases.push({ img: { data: data, width: img8.width, height: img8.height }, label: '暗反色码(反转+Otsu)', expect: '12345' });
|
||
})();
|
||
|
||
// 原图再识别:验证预处理未污染原始数据
|
||
builtCases.push({ img: img8, label: '原图再识别(数据未污染)', expect: '12345' });
|
||
|
||
// ---------- 执行 ----------
|
||
var tasks = [];
|
||
fileCases.forEach(function (c) {
|
||
tasks.push(server.decodeByPath(path.join(__dirname, c.path))
|
||
.then(function (txt) { check(c.label, txt, c.expect); })
|
||
.catch(function (e) { failCount++; console.log('FAIL ' + c.label + ' => ' + e); }));
|
||
});
|
||
builtCases.forEach(function (c) {
|
||
tasks.push(Promise.resolve().then(function () {
|
||
try { check(c.label, qrDecode(c.img), c.expect); }
|
||
catch (e) { failCount++; console.log('FAIL ' + c.label + ' => ' + e); }
|
||
}));
|
||
});
|
||
|
||
Promise.all(tasks).then(function () {
|
||
console.log('');
|
||
console.log('========================');
|
||
console.log('综合回归:通过 ' + passCount + ' / 失败 ' + failCount);
|
||
process.exit(failCount > 0 ? 1 : 0);
|
||
});
|