2020-05-14 13:42:15 +00:00
|
|
|
import React, {useEffect, useMemo, useState} from "react";
|
|
|
|
import {gamma} from "../../utils/util";
|
2020-05-14 12:07:09 +00:00
|
|
|
import {ParamTypes} from "../../constant/ParamTypes";
|
|
|
|
import {getTypeTable, QRPointType} from "../../utils/qrcodeHandler";
|
|
|
|
|
|
|
|
function listPoints(qrcode, params) {
|
|
|
|
if (!qrcode) return []
|
|
|
|
|
|
|
|
const nCount = qrcode.getModuleCount();
|
|
|
|
const typeTable = getTypeTable(qrcode);
|
|
|
|
const pointList = new Array(nCount);
|
2020-05-14 14:07:02 +00:00
|
|
|
let alignType = params[1];
|
|
|
|
let timingType = params[2];
|
2020-05-15 03:37:31 +00:00
|
|
|
let otherColor = params[3];
|
|
|
|
let posColor = params[4];
|
2020-05-14 12:07:09 +00:00
|
|
|
|
|
|
|
let id = 0;
|
|
|
|
for (let x = 0; x < nCount; x++) {
|
|
|
|
for (let y = 0; y < nCount; y++) {
|
2020-05-14 12:31:21 +00:00
|
|
|
const posX = 3 * x, posY = 3 * y;
|
2020-05-14 14:07:02 +00:00
|
|
|
if (typeTable[x][y] == QRPointType.ALIGN_CENTER || typeTable[x][y] == QRPointType.ALIGN_OTHER) {
|
2020-05-14 12:07:09 +00:00
|
|
|
if (qrcode.isDark(x, y)) {
|
2020-05-14 14:07:02 +00:00
|
|
|
if (alignType === 2) {
|
2020-05-15 03:37:31 +00:00
|
|
|
pointList.push(<use key={id++} xlinkHref="#B-black" x={posX - 0.03} y={posY - 0.03}/>)
|
2020-05-14 14:07:02 +00:00
|
|
|
} else {
|
2020-05-15 03:37:31 +00:00
|
|
|
pointList.push(<use key={id++} xlinkHref="#S-black" x={posX + 1 - 0.01} y={posY + 1 - 0.01}/>)
|
2020-05-14 14:07:02 +00:00
|
|
|
}
|
2020-05-14 12:07:09 +00:00
|
|
|
} else {
|
2020-05-14 14:07:02 +00:00
|
|
|
if (alignType === 0) {
|
|
|
|
pointList.push(<use key={id++} xlinkHref="#S-white" x={posX + 1} y={posY + 1}/>)
|
|
|
|
} else {
|
2020-05-15 03:37:31 +00:00
|
|
|
pointList.push(<use key={id++} xlinkHref="#B-white" x={posX - 0.03} y={posY - 0.03}/>)
|
2020-05-14 14:07:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (typeTable[x][y] == QRPointType.TIMING) {
|
|
|
|
if (qrcode.isDark(x, y)) {
|
|
|
|
if (timingType === 2) {
|
2020-05-15 03:37:31 +00:00
|
|
|
pointList.push(<use key={id++} xlinkHref="#B-black" x={posX - 0.03} y={posY - 0.03}/>)
|
2020-05-14 14:07:02 +00:00
|
|
|
} else {
|
|
|
|
pointList.push(<use key={id++} xlinkHref="#S-black" x={posX + 1} y={posY + 1}/>)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (timingType === 0) {
|
|
|
|
pointList.push(<use key={id++} xlinkHref="#S-white" x={posX + 1} y={posY + 1}/>)
|
|
|
|
} else {
|
2020-05-15 03:37:31 +00:00
|
|
|
pointList.push(<use key={id++} xlinkHref="#B-white" x={posX - 0.03} y={posY - 0.03}/>)
|
2020-05-14 14:07:02 +00:00
|
|
|
}
|
2020-05-14 12:07:09 +00:00
|
|
|
}
|
|
|
|
} else if (typeTable[x][y] == QRPointType.POS_CENTER) {
|
|
|
|
if (qrcode.isDark(x, y)) {
|
2020-05-15 03:37:31 +00:00
|
|
|
pointList.push(<use key={id++} fill={posColor} xlinkHref="#B" x={posX - 0.03} y={posY - 0.03}/>)
|
2020-05-14 12:07:09 +00:00
|
|
|
}
|
|
|
|
} else if (typeTable[x][y] == QRPointType.POS_OTHER) {
|
|
|
|
if (qrcode.isDark(x, y)) {
|
2020-05-15 03:37:31 +00:00
|
|
|
pointList.push(<use key={id++} fill={posColor} xlinkHref="#B" x={posX - 0.03} y={posY - 0.03}/>)
|
2020-05-14 12:07:09 +00:00
|
|
|
} else {
|
2020-05-15 03:37:31 +00:00
|
|
|
pointList.push(<use key={id++} xlinkHref="#B-white" x={posX - 0.03} y={posY - 0.03}/>)
|
2020-05-14 12:07:09 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (qrcode.isDark(x, y)) {
|
2020-05-14 12:31:21 +00:00
|
|
|
pointList.push(<use key={id++} xlinkHref="#S-black" x={posX + 1} y={posY + 1}/>)
|
2020-05-14 12:07:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pointList;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getParamInfo() {
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
type: ParamTypes.UPLOAD_BUTTON,
|
|
|
|
key: '背景图片',
|
2020-05-14 14:07:02 +00:00
|
|
|
default: data,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: ParamTypes.SELECTOR,
|
|
|
|
key: '小定位点样式',
|
2020-05-14 12:07:09 +00:00
|
|
|
default: 0,
|
2020-05-14 14:07:02 +00:00
|
|
|
choices: [
|
|
|
|
"无",
|
|
|
|
"白",
|
|
|
|
"黑白",
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: ParamTypes.SELECTOR,
|
|
|
|
key: '时钟样式',
|
|
|
|
default: 0,
|
|
|
|
choices: [
|
|
|
|
"无",
|
|
|
|
"白",
|
|
|
|
"黑白",
|
|
|
|
]
|
|
|
|
},
|
2020-05-15 03:37:31 +00:00
|
|
|
{
|
|
|
|
type: ParamTypes.COLOR_EDITOR,
|
|
|
|
key: '信息点颜色',
|
|
|
|
default: '#000000'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: ParamTypes.COLOR_EDITOR,
|
|
|
|
key: '定位点颜色',
|
|
|
|
default: '#000000'
|
|
|
|
},
|
2020-05-14 12:07:09 +00:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getViewBox(qrcode) {
|
|
|
|
if (!qrcode) return '0 0 0 0';
|
|
|
|
|
|
|
|
const nCount = qrcode.getModuleCount() * 3;
|
|
|
|
return String(-nCount / 5) + ' ' + String(-nCount / 5) + ' ' + String(nCount + nCount / 5 * 2) + ' ' + String(nCount + nCount / 5 * 2);
|
|
|
|
}
|
|
|
|
|
2020-05-14 13:42:15 +00:00
|
|
|
function getGrayPointList(imgBase64, size, black, white) {
|
|
|
|
let canvas = document.createElement('canvas');
|
|
|
|
let ctx = canvas.getContext('2d');
|
|
|
|
let img = document.createElement('img');
|
|
|
|
let gpl = [];
|
|
|
|
canvas.style.imageRendering = 'pixelated';
|
|
|
|
size *= 3;
|
|
|
|
|
|
|
|
img.src = imgBase64;
|
|
|
|
return new Promise(resolve => {
|
|
|
|
img.onload = () => {
|
|
|
|
canvas.width = size;
|
|
|
|
canvas.height = size;
|
|
|
|
ctx.imageSmoothingEnabled = false;
|
|
|
|
ctx.drawImage(img, 0, 0, size, size);
|
|
|
|
|
|
|
|
for (let x = 0; x < canvas.width; x++) {
|
|
|
|
for (let y = 0; y < canvas.height; y++) {
|
|
|
|
let imageData = ctx.getImageData(x, y, 1, 1);
|
|
|
|
let data = imageData.data;
|
|
|
|
let gray = gamma(data[0], data[1], data[2]);
|
2020-05-15 03:37:31 +00:00
|
|
|
if (Math.random() > gray / 255 && ( x % 3 !== 1 || y % 3 !== 1 ) ) gpl.push(<use key={"g_" + x + "_" + y} x={x} y={y} xlinkHref={black} />);
|
2020-05-14 13:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
resolve(gpl);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-05-14 12:07:09 +00:00
|
|
|
const RendererResImage = ({qrcode, params, setParamInfo}) => {
|
2020-05-15 03:37:31 +00:00
|
|
|
let otherColor = params[3];
|
|
|
|
let posColor = params[4];
|
|
|
|
|
2020-05-14 12:07:09 +00:00
|
|
|
useEffect(() => {
|
|
|
|
setParamInfo(getParamInfo());
|
|
|
|
}, [setParamInfo]);
|
|
|
|
|
|
|
|
const [gpl, setGPL] = useState([]);
|
2020-05-14 13:42:15 +00:00
|
|
|
useMemo(() => {
|
2020-05-14 12:31:21 +00:00
|
|
|
getGrayPointList(params[0], qrcode.getModuleCount(), "#S-black", "#S-white").then(res => setGPL(res));
|
2020-05-14 13:42:15 +00:00
|
|
|
}, [setGPL, params[0], qrcode])
|
2020-05-14 12:07:09 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<svg className="Qr-item-svg" width="100%" height="100%" viewBox={getViewBox(qrcode)} fill="white"
|
|
|
|
xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
|
|
|
|
<defs>
|
2020-05-15 03:37:31 +00:00
|
|
|
<rect id="B-black" fill={otherColor} width={3.08} height={3.08}/>
|
|
|
|
<rect id="B-white" fill="white" width={3.08} height={3.08}/>
|
|
|
|
<rect id="S-black" fill={otherColor} width={1.02} height={1.02}/>
|
|
|
|
<rect id="S-white" fill="white" width={1.02} height={1.02}/>
|
|
|
|
<rect id="B" width={3.08} height={3.08}/>
|
|
|
|
<rect id="S" width={1.02} height={1.02}/>
|
2020-05-14 12:07:09 +00:00
|
|
|
</defs>
|
|
|
|
{gpl.concat(listPoints(qrcode, params))}
|
|
|
|
</svg>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-05-14 14:07:02 +00:00
|
|
|
let data = "data:image/jpg;base64,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
|
|
|
|
|
2020-05-14 12:07:09 +00:00
|
|
|
export default RendererResImage
|