亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript實(shí)現(xiàn)讀取條碼中的二進(jìn)制數(shù)據(jù)

 更新時(shí)間:2024年03月21日 14:36:45   作者:xulihang  
條碼是一種以機(jī)器可讀的可視形式表示數(shù)據(jù)的方法,我們可以從條碼獲取二進(jìn)制數(shù)據(jù),并通過不同方法去讀碼,下面我們就來看看如何實(shí)現(xiàn)讀取條碼中的二進(jìn)制數(shù)據(jù)吧

條碼是一種以機(jī)器可讀的可視形式表示數(shù)據(jù)的方法。條碼種類繁多,主要分為一維碼和二維碼。

我們可以從條碼獲取二進(jìn)制數(shù)據(jù),并通過不同方法去讀碼。例如,在EAN-13中,位于其右邊的代碼1110010代表數(shù)字0。而QR碼,它是二維的,可以存儲更多的數(shù)據(jù),有幾種表示數(shù)據(jù)的模式:

輸入模式模式標(biāo)識最大字符數(shù)允許的字符,默認(rèn)編碼
僅數(shù)字17,0890、1、2、3、4、5、6、7、8、9
字母與數(shù)字24,2960-9、A-Z(僅限大寫)、空格、$、%、*、+、-、..、/、:
二進(jìn)制/字節(jié)42,953ISO/IEC 8859-1
日語漢字/假名81,817Shift JIS X 0208
結(jié)構(gòu)化追加3無限沒有限定

PS:結(jié)構(gòu)化追加(Structured Append)是一種將數(shù)據(jù)分到多個(gè)條碼的模式。

在本文中,我們將創(chuàng)建一個(gè)用于讀取條碼二進(jìn)制數(shù)據(jù)的JavaScript庫,并重點(diǎn)處理QR碼,因?yàn)檫@種碼型有多種模式。

Dynamsoft Barcode Reader會(huì)被用于讀取條碼。

新建項(xiàng)目

使用Vite創(chuàng)建一個(gè)新的TypeScript項(xiàng)目:

npm create vite@latest BarcodeDataReader -- --template vanilla-ts

編寫定義

為讀取條碼的二進(jìn)制數(shù)據(jù)定義幾個(gè)接口和一個(gè)枚舉。

定義BarcodeDetail接口:

export interface BarcodeDetail {
  mode?:number; //The data encoding mode
  model?:number; //Number of models
  errorCorrectionLevel?:number;
  columns?:number; //The column count
  rows?:number; //The row count
  page?:number; //Position of the particular code in structured append codes
  totalPage?:number; //Total number of structured append codes
  parityData?:number; //A value obtained by XORing byte by byte the ASCII/JIS values of all the original input data before division into symbol blocks.
  version?:number; //The version of the code.
}

定義Barcode接口:

export interface Barcode {
  bytes:Uint8Array;
  details:BarcodeDetail;
  barcodeType?:string;
}

二進(jìn)制數(shù)據(jù)存儲為Uint8Array。

定義ReadingResult接口:

export interface ReadingResult {
  text?:string;
  img?:HTMLImageElement;
  blob?:Blob;
}

我們可以得到純文本、HTML圖像元素或blob這三種類型的結(jié)果。

類型需要在DataType中指定。

export enum DataType {
  text = 0,
  image = 1,
  unknown = 2
}

創(chuàng)建一個(gè)讀取二進(jìn)制數(shù)據(jù)的類

使用以下模板創(chuàng)建一個(gè)新的BarcodeDataReader.ts文件:

export class BarcodeDataReader{
  async read(barcodes:Barcode[],dataType:DataType):Promise<ReadingResult[]>{
    if (barcodes.length == 0) {
      throw new Error("No barcodes given");
    }
    let results:ReadingResult[] = [];
    return results;
  }
}

根據(jù)不同模式讀取二進(jìn)制數(shù)據(jù)。

async read(barcodes:Barcode[],dataType:DataType):Promise<ReadingResult[]>{
  if (barcodes.length == 0) {
    throw new Error("No barcodes given");
  }
  let results:ReadingResult[] = [];
  const mode = barcodes[0].details.mode;
  if (mode == 1) {
    results = this.readNumericBarcodes(barcodes);
  }else if (mode == 2) {
    results = this.readAlphaNumericBarcodes(barcodes);
  }else if (mode == 4) {
    results = await this.readByteEncodingBarcodes(barcodes,dataType);
  }else if (mode == 8) {
    results = this.readKanjiBarcodes(barcodes);
  }else if (mode == 3) {
    results = await this.readStructuredAppendBarcodes(barcodes,dataType);
  }else {
    results = await this.readByteEncodingBarcodes(barcodes,DataType.text);
  }
  return results;
}

實(shí)現(xiàn)對數(shù)字、字母與數(shù)字和日文漢字模式的讀取。這三種模式的數(shù)據(jù)都是純文本,它們可以共享類似的邏輯。

private readAlphaNumericBarcodes(barcodes:Barcode[]):ReadingResult[]{
  return this.decodeText(barcodes,"ASCII");
}

private readNumericBarcodes(barcodes:Barcode[]):ReadingResult[]{
  return this.decodeText(barcodes,"ASCII");
}

private readKanjiBarcodes(barcodes:Barcode[]):ReadingResult[]{
  return this.decodeText(barcodes,"SHIFT-JIS");
}

private decodeText(barcodes:Barcode[],encoding:string){
  let results:ReadingResult[] = [];
  for (let index = 0; index < barcodes.length; index++) {
    const barcode = barcodes[index];
    const decoder = new TextDecoder(encoding);
    const text = decoder.decode(barcode.bytes);
    let result = {
      text:text
    }
    results.push(result);
  }
  return results;
}

以字節(jié)模式讀取數(shù)據(jù)。

由于字節(jié)模式下的數(shù)據(jù)類型未知,我們需要根據(jù)用戶指定的數(shù)據(jù)類型獲取讀取結(jié)果。

如果數(shù)據(jù)類型是文本,我們需要檢測編碼。這里使用chardet庫進(jìn)行檢測。

private async readByteEncodingBarcodes(barcodes:Barcode[],dataType:DataType):Promise<ReadingResult[]>{
  let results:ReadingResult[] = [];
  for (let index = 0; index < barcodes.length; index++) {
    const barcode = barcodes[index];
    let result:ReadingResult = await this.getResultBasedOnDataType(barcode.bytes,dataType);
    results.push(result);
  }
  return results;
}

async getResultBasedOnDataType(data:Uint8Array,dataType:DataType) {
  let result:ReadingResult;
  if (dataType == DataType.text) {
    const charset = chardet.analyse(data);
    const decoder = new TextDecoder(charset[0].name);
    const text = decoder.decode(data);
    result = {
      text:text
    }
  }else if (dataType == DataType.image) {
    const img = await this.getImageFromUint8Array(data);
    result = {
      img:img
    }
  }else{
    result = {
      blob:this.getBlobFromUint8Array(data)
    }
  }
  return result;
}

getBlobFromUint8Array(data:Uint8Array) {
  return new Blob([data]);
}
getImageFromUint8Array(data:Uint8Array):Promise<HTMLImageElement>{
  return new Promise<HTMLImageElement>((resolve, reject) => {
    const img = document.createElement("img");  
    const blob = this.getBlobFromUint8Array(data);
    img.onload = function(){
      resolve(img);
    }
    img.onerror = function(error) {
      console.error(error);
      reject(error);
    }
    img.src = URL.createObjectURL(blob);
    console.log(img.src)
  })
}

以結(jié)構(gòu)化追加模式讀取數(shù)據(jù)。

需要根據(jù)頁碼對條碼進(jìn)行排序,將多個(gè)碼的數(shù)據(jù)合并成一個(gè)Unit8Array,然后得到結(jié)果。

private async readStructuredAppendBarcodes(barcodes:Barcode[],dataType:DataType):Promise<ReadingResult[]>{
  let results:ReadingResult[] = [];
  barcodes.sort((a, b) => (a.details.page ?? 0) - (b.details.page ?? 0))
  let concatedData:Uint8Array = new Uint8Array();
  for (let index = 0; index < barcodes.length; index++) {
    const barcode = barcodes[index];
    let merged = new Uint8Array(barcode.bytes.length + concatedData.length);
    merged.set(concatedData);
    merged.set(barcode.bytes, concatedData.length);
    concatedData = merged;
  }
  let result = await this.getResultBasedOnDataType(concatedData,dataType);
  results.push(result);
  return results;
}

讀取測試

然后,我們可以更新index.html,使用Dynamsoft Barcode Reader讀取QR碼,并使用我們編寫的庫讀取二進(jìn)制數(shù)據(jù)。

以下是基本代碼:

let router = await Dynamsoft.CVR.CaptureVisionRouter.createInstance();
//read barcodes from an image
let result = await router.capture(document.getElementById("image"),"ReadBarcodes_Balance");
let dataType = document.getElementById("dataTypeSelect").selectedIndex;
let barcodes = [];
for (let index = 0; index < result.items.length; index++) {
  const item = result.items[index];
  if (item.type === Dynamsoft.Core.EnumCapturedResultItemType.CRIT_BARCODE) {
    let data = new Uint8Array(item.bytes.length);
    data.set(item.bytes);
    let barcode = {
      bytes:data,
      details:item.details
    }
    barcodes.push(barcode);
  }
}

let results = await dataReader.read(barcodes,dataType)
console.log(results);

可以訪問在線演示進(jìn)行試用。

如果手頭沒有二維碼,可以使用此文中的二維碼和二維碼生成器。

下面是讀取兩個(gè)二維碼的測試截圖,一張圖片被編碼在這兩個(gè)二維碼中:

打包為庫

為了便于使用,我們可以將其作為庫發(fā)布到NPM上。

安裝devDependencies

npm install -D @types/node vite-plugin-dts

創(chuàng)建一個(gè)新的vite.config.ts文件:

// vite.config.ts
import { resolve } from 'path';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
// https://vitejs.dev/guide/build.html#library-mode
export default defineConfig({
  build: {
    lib: {
      entry: resolve(__dirname, 'src/index.ts'),
      name: 'barcode-data-reader',
      fileName: 'barcode-data-reader',
    },
  },
  plugins: [dts()],
});

將我們的包的入口點(diǎn)添加到package.json。

{
  "main": "./dist/barcode-data-reader.umd.cjs",
  "module": "./dist/barcode-data-reader.js",
  "types": "./dist/index.d.ts",
  "exports": {
    "import": {
      "types": "./dist/index.d.ts",
      "default": "./dist/barcode-data-reader.js"
    },
    "require": {
      "types": "./dist/index.d.ts",
      "default": "./dist/barcode-data-reader.umd.cjs"
    }
  },
  "files": [
    "dist/*.css",
    "dist/*.js",
    "dist/*.cjs",
    "dist/*.d.ts"
  ]
}

運(yùn)行npm run build。然后,我們可以在dist文件夾中看到打包好的文件。

源代碼

歡迎下載源代碼并嘗試使用:

github.com/tony-xlh/barcode-data-reader

以上就是JavaScript實(shí)現(xiàn)讀取條碼中的二進(jìn)制數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript讀取條碼二進(jìn)制數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論