[QR scan]
This commit is contained in:
parent
52b2b75f95
commit
e26b286079
|
@ -8091,6 +8091,11 @@
|
|||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"jsqr": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npm.taobao.org/jsqr/download/jsqr-1.3.1.tgz",
|
||||
"integrity": "sha1-UVp2bliwDIAULzotxLh1EQDO7c8="
|
||||
},
|
||||
"jsx-ast-utils": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npm.taobao.org/jsx-ast-utils/download/jsx-ast-utils-2.2.3.tgz",
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
"jsqr": "^1.3.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.13.1",
|
||||
"react-color": "^2.18.1",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from 'react';
|
||||
import './App.css';
|
||||
import '../Qrcode.css';
|
||||
import Footer from "../footer/Footer";
|
||||
import Header from "../header/Header";
|
||||
import PartFooter from "./PartFooter";
|
||||
import PartHeader from "./PartHeader";
|
||||
import PartMore from "./PartMore";
|
||||
import PartParams from "./PartParams";
|
||||
import PartDownloadViewer from "../../containers/app/PartDownloadViewer";
|
||||
|
@ -14,12 +14,12 @@ function App() {
|
|||
<header className="App-header">
|
||||
<div className="Layout">
|
||||
<div className="Qr-outer">
|
||||
<Header/>
|
||||
<PartHeader/>
|
||||
<PartStylesViewer/>
|
||||
<PartParams/>
|
||||
<PartDownloadViewer/>
|
||||
<PartMore/>
|
||||
<Footer/>
|
||||
<PartFooter/>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
|
|
@ -3,7 +3,7 @@ import '../Qrcode.css';
|
|||
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
const Footer = () => (
|
||||
const PartFooter = () => (
|
||||
<div className="Qr-titled">
|
||||
<div className="Qr-Centered Qr-footer note-font">
|
||||
<div>
|
||||
|
@ -33,4 +33,4 @@ const Footer = () => (
|
|||
</div>
|
||||
)
|
||||
|
||||
export default Footer
|
||||
export default PartFooter
|
|
@ -9,7 +9,7 @@ const logoStyle = {
|
|||
backgroundPosition: 'left'
|
||||
};
|
||||
|
||||
const Header = () => (
|
||||
const PartHeader = () => (
|
||||
<div className="Qr-Centered">
|
||||
<div style={logoStyle}>
|
||||
<h1 className="Qr-title"> </h1>
|
||||
|
@ -19,4 +19,4 @@ const Header = () => (
|
|||
</div>
|
||||
)
|
||||
|
||||
export default Header
|
||||
export default PartHeader
|
|
@ -1,7 +1,5 @@
|
|||
import React, { useEffect } from "react";
|
||||
import {defaultViewBox, rand} from "../../utils/util";
|
||||
import {ParamTypes} from "../../constant/ParamTypes";
|
||||
import {getTypeTable, QRPointType} from "../../utils/qrcodeHandler";
|
||||
|
||||
function listPoints(qrcode, params) {
|
||||
if (!qrcode) return []
|
||||
|
|
|
@ -167,7 +167,7 @@ const RendererResImage = ({qrcode, params, setParamInfo}) => {
|
|||
const [gpl, setGPL] = useState([]);
|
||||
useMemo(() => {
|
||||
getGrayPointList(params, qrcode.getModuleCount(), "#S-black", "#S-white").then(res => setGPL(res));
|
||||
}, [setGPL, params[0], params[1], params[2], qrcode])
|
||||
}, [setGPL, params, qrcode])
|
||||
|
||||
return (
|
||||
<svg className="Qr-item-svg" width="100%" height="100%" viewBox={getViewBox(qrcode)} fill="white"
|
||||
|
|
|
@ -3,5 +3,5 @@ export const actionTypes = {
|
|||
CHANGE_STYLE: 'CHANGE_STYLE',
|
||||
CHANGE_CORRECT_LEVEL: 'CHANGE_CORRECT_LEVEL',
|
||||
CREATE_PARAM: 'CREATE_PARAM',
|
||||
CHANGE_PARAM: 'CHANGE_PARAM'
|
||||
CHANGE_PARAM: 'CHANGE_PARAM',
|
||||
}
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
import {connect} from 'react-redux';
|
||||
import {genQRInfo} from "../../actions";
|
||||
import React from "react";
|
||||
import React, {useRef} from "react";
|
||||
import {isPicture} from "../../utils/util";
|
||||
import {decodeData} from "../../utils/qrcodeHandler";
|
||||
|
||||
const InputText = ({dispatch}) => (
|
||||
const InputText = ({dispatch}) => {
|
||||
const textRef = useRef();
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<input
|
||||
className="Qr-input big-input"
|
||||
placeholder="Input your URL here"
|
||||
ref={textRef}
|
||||
onBlur={e => dispatch(genQRInfo(e.target.value))}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
|
@ -14,6 +21,35 @@ const InputText = ({dispatch}) => (
|
|||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
<label
|
||||
htmlFor="image_scanner"
|
||||
className="dl-btn"
|
||||
style={{textAlign: "center"}}
|
||||
>
|
||||
扫描图片
|
||||
</label>
|
||||
<input
|
||||
type="file"
|
||||
id="image_scanner"
|
||||
hidden={true}
|
||||
accept=".jpg, .jpeg, .png"
|
||||
onClick={(e) => e.target.value = null}
|
||||
onChange={(e) => {
|
||||
if (e.target.files.length > 0) {
|
||||
const file = e.target.files[0];
|
||||
if (isPicture(file)) {
|
||||
decodeData(file).then((res) => {
|
||||
if (res) {
|
||||
textRef.current.value = res.data;
|
||||
console.log(res.data)
|
||||
dispatch(genQRInfo(res.data))
|
||||
}
|
||||
}).catch(console.err);
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</React.Fragment>);
|
||||
}
|
||||
|
||||
export default connect()(InputText);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { connect } from 'react-redux';
|
||||
import PartDownload from "../../components/app/PartDownload";
|
||||
import React from "react";
|
||||
import {saveImg, saveSvg} from "../../utils/downloader";
|
||||
import {increaseDownloadData, recordDownloadDetail} from "../../api/db";
|
||||
import {getParamDetailedValue, outerHtml} from "../../utils/util";
|
||||
|
|
|
@ -1,17 +1,7 @@
|
|||
import { connect } from 'react-redux';
|
||||
import {changeParam} from "../../actions";
|
||||
import ParamUpload from "../../components/param/ParamUpload";
|
||||
import {toBase64} from "../../utils/util";
|
||||
|
||||
const fileTypes =[
|
||||
'image/jpeg',
|
||||
'image/pjpeg',
|
||||
'image/png'
|
||||
]
|
||||
|
||||
function validFileType(file) {
|
||||
return fileTypes.includes(file.type);
|
||||
}
|
||||
import {isPicture, toBase64} from "../../utils/util";
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
rendererIndex: ownProps.rendererIndex,
|
||||
|
@ -24,7 +14,7 @@ const mapDispatchToProps = (dispatch, ownProps) => ({
|
|||
onChange: (e) => {
|
||||
if (e.target.files.length > 0) {
|
||||
const file = e.target.files[0];
|
||||
if (validFileType(file)) {
|
||||
if (isPicture(file)) {
|
||||
toBase64(file, 500, 500).then(res => {
|
||||
dispatch(changeParam(ownProps.rendererIndex, ownProps.paramIndex, res))
|
||||
})
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import {connect, useDispatch} from 'react-redux';
|
||||
import {changeStyle, createParam} from "../../actions";
|
||||
import {connect} from 'react-redux';
|
||||
import {changeStyle} from "../../actions";
|
||||
import StyleList from "../../components/style/StyleList";
|
||||
import RendererViewer from "./RendererViewer";
|
||||
import RendererBlank from "../../components/renderer/RendererBlank";
|
||||
import RendererBase from "../../components/renderer/RendererBase";
|
||||
import RendererDSJ from "../../components/renderer/RendererDSJ";
|
||||
import RendererRound from "../../components/renderer/RendererRound";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {getQrcodeData} from "../utils/qrcodeHandler";
|
||||
import {encodeData} from "../utils/qrcodeHandler";
|
||||
import {actionTypes} from "../constant/ActionTypes";
|
||||
import {QRBTF_URL} from "../constant/References";
|
||||
import RendererBase from "../components/renderer/RendererBase";
|
||||
|
@ -11,7 +11,7 @@ const initialState = {
|
|||
correctLevel: 0,
|
||||
textUrl: QRBTF_URL,
|
||||
history: [],
|
||||
qrcode: getQrcodeData({text: QRBTF_URL, correctLevel: 0}),
|
||||
qrcode: encodeData({text: QRBTF_URL, correctLevel: 0}),
|
||||
paramInfo: new Array(16).fill(new Array(16)),
|
||||
paramValue: new Array(16).fill(new Array(16))
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ export default function appReducer(state = initialState, action) {
|
|||
if (!text || text.length == 0) text = QRBTF_URL;
|
||||
return Object.assign({}, state, {
|
||||
textUrl: text,
|
||||
qrcode: getQrcodeData({text: text, correctLevel: state.correctLevel})
|
||||
qrcode: encodeData({text: text, correctLevel: state.correctLevel})
|
||||
});
|
||||
}
|
||||
case actionTypes.CHANGE_STYLE: {
|
||||
|
@ -37,7 +37,7 @@ export default function appReducer(state = initialState, action) {
|
|||
case actionTypes.CHANGE_CORRECT_LEVEL: {
|
||||
return Object.assign({}, state, {
|
||||
correctLevel: parseInt(action.correctLevel),
|
||||
qrcode: getQrcodeData({text: state.textUrl, correctLevel: parseInt(action.correctLevel)})
|
||||
qrcode: encodeData({text: state.textUrl, correctLevel: parseInt(action.correctLevel)})
|
||||
})
|
||||
}
|
||||
case actionTypes.CREATE_PARAM: {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
/* eslint-disable */
|
||||
function QR8bitByte(data) {
|
||||
this.mode = QRMode.MODE_8BIT_BYTE;
|
||||
this.data = data;
|
||||
|
@ -1270,4 +1271,4 @@ QRBitBuffer.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
export default QRCode
|
||||
exports.qrcode = QRCode;
|
|
@ -1,4 +1,5 @@
|
|||
import QRCode from "./qrcode";
|
||||
import { qrcode as QRCodeEncoder } from "./qrcodeEncoder";
|
||||
import jsQR from "jsqr";
|
||||
|
||||
function extend(target, options) {
|
||||
for (let name in options) {
|
||||
|
@ -18,7 +19,7 @@ export var QRPointType = {
|
|||
VERSION: 7
|
||||
}
|
||||
|
||||
export function getQrcodeData(options) {
|
||||
export function encodeData(options) {
|
||||
if (!options.text || options.text.length <= 0) return null
|
||||
|
||||
options = extend({
|
||||
|
@ -31,7 +32,7 @@ export function getQrcodeData(options) {
|
|||
foreground : "#000000"
|
||||
}, options);
|
||||
|
||||
let qrcode = new QRCode(options.typeNumber, options.correctLevel)
|
||||
let qrcode = new QRCodeEncoder(options.typeNumber, options.correctLevel)
|
||||
qrcode.addData(options.text)
|
||||
qrcode.make()
|
||||
|
||||
|
@ -90,3 +91,26 @@ export function getTypeTable(qrcode) {
|
|||
}
|
||||
return typeTable;
|
||||
}
|
||||
|
||||
export function decodeData(file) {
|
||||
let canvas = document.createElement('canvas');
|
||||
let ctx = canvas.getContext('2d');
|
||||
let img = document.createElement('img');
|
||||
const maxSize = 400;
|
||||
|
||||
img.setAttribute('src', URL.createObjectURL(file));
|
||||
return new Promise((resolve) => {
|
||||
img.onload = () => {
|
||||
let rate = Math.min(img.width, img.height) / maxSize;
|
||||
|
||||
canvas.width = img.width / rate;
|
||||
canvas.height = img.height / rate;
|
||||
|
||||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
let result = jsQR(
|
||||
ctx.getImageData(0, 0, canvas.width, canvas.height).data, canvas.width, canvas.height);
|
||||
resolve(result);
|
||||
};
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
import {ParamTypes} from "../constant/ParamTypes";
|
||||
import React from "react";
|
||||
|
||||
let seed = 0;
|
||||
|
||||
const fileTypes =[
|
||||
'image/jpeg',
|
||||
'image/pjpeg',
|
||||
'image/png'
|
||||
]
|
||||
|
||||
export function isPicture(file) {
|
||||
return fileTypes.includes(file.type);
|
||||
}
|
||||
|
||||
|
||||
export function srand(sd) {
|
||||
seed = sd;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue