or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-jsqr

A pure JavaScript QR code reading library that processes raw images to locate, extract and parse QR codes.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/jsqr@1.4.x

To install, run

npx @tessl/cli install tessl/npm-jsqr@1.4.0

0

# jsQR

1

2

jsQR is a pure JavaScript QR code reading library that processes raw image data to locate, extract and parse QR codes. It operates entirely in JavaScript without external dependencies, making it suitable for both browser and Node.js environments.

3

4

## Package Information

5

6

- **Package Name**: jsqr

7

- **Package Type**: npm

8

- **Language**: TypeScript/JavaScript

9

- **Installation**: `npm install jsqr`

10

11

## Core Imports

12

13

```javascript

14

// ES6 import

15

import jsQR from "jsqr";

16

17

// CommonJS require

18

const jsQR = require("jsqr");

19

```

20

21

For browser usage with script tag:

22

```html

23

<script src="jsQR.js"></script>

24

<script>

25

// jsQR is available globally

26

</script>

27

```

28

29

## Basic Usage

30

31

```javascript

32

import jsQR from "jsqr";

33

34

// Get RGBA image data from canvas, image, or other source

35

const imageData = canvas.getContext('2d').getImageData(0, 0, width, height);

36

37

// Process the image data

38

const code = jsQR(imageData.data, imageData.width, imageData.height);

39

40

if (code) {

41

console.log("Found QR code:", code.data);

42

console.log("Location:", code.location);

43

} else {

44

console.log("No QR code found");

45

}

46

```

47

48

## Capabilities

49

50

### QR Code Detection and Decoding

51

52

Processes raw RGBA image data to find and decode QR codes, returning comprehensive information about the decoded content and location.

53

54

```javascript { .api }

55

/**

56

* Scans image data for QR codes and returns decoded information

57

* @param data - RGBA pixel data as Uint8ClampedArray [r0,g0,b0,a0,r1,g1,b1,a1,...]

58

* @param width - Image width in pixels

59

* @param height - Image height in pixels

60

* @param providedOptions - Optional scanning configuration

61

* @returns Decoded QR code data or null if no valid QR code found

62

*/

63

function jsQR(

64

data: Uint8ClampedArray,

65

width: number,

66

height: number,

67

providedOptions?: Options

68

): QRCode | null;

69

```

70

71

**Parameters:**

72

- `data` - An `Uint8ClampedArray` of RGBA pixel values in the form `[r0, g0, b0, a0, r1, g1, b1, a1, ...]`. The length should be `4 * width * height`. This matches the format of browser `ImageData` interface and common Node.js image processing libraries.

73

- `width` - The width of the image in pixels

74

- `height` - The height of the image in pixels

75

- `providedOptions` (optional) - Configuration options for scanning behavior

76

77

**Returns:**

78

- `QRCode` object if a valid QR code is found and successfully decoded

79

- `null` if no QR code is found or decoding fails

80

81

## Types

82

83

```javascript { .api }

84

interface Options {

85

/**

86

* Image inversion strategy for finding QR codes on different backgrounds

87

* - "attemptBoth": Try both normal and inverted (default, ~50% performance hit)

88

* - "dontInvert": Only scan normal image

89

* - "onlyInvert": Only scan inverted image

90

* - "invertFirst": Try inverted first, then normal if no result

91

*/

92

inversionAttempts?: "dontInvert" | "onlyInvert" | "attemptBoth" | "invertFirst";

93

}

94

95

interface QRCode {

96

/** Raw bytes of the QR code as numeric array */

97

binaryData: number[];

98

/** Decoded string content of the QR code */

99

data: string;

100

/** Array of decoded data chunks with encoding information */

101

chunks: Chunks;

102

/** QR code version number (1-40, indicating size and capacity) */

103

version: number;

104

/** Precise pixel coordinates of key QR code features */

105

location: {

106

/** Corner coordinates of the decoded QR code area */

107

topRightCorner: Point;

108

topLeftCorner: Point;

109

bottomRightCorner: Point;

110

bottomLeftCorner: Point;

111

/** Finder pattern centers (the square detection patterns) */

112

topRightFinderPattern: Point;

113

topLeftFinderPattern: Point;

114

bottomLeftFinderPattern: Point;

115

/** Alignment pattern center (may not exist for smaller QR codes) */

116

bottomRightAlignmentPattern?: Point;

117

};

118

}

119

120

interface Point {

121

/** X coordinate in pixels */

122

x: number;

123

/** Y coordinate in pixels */

124

y: number;

125

}

126

127

type Chunks = Array<Chunk | ByteChunk | ECIChunk>;

128

129

interface Chunk {

130

/** Data encoding mode used for this chunk */

131

type: Mode;

132

/** Decoded text content */

133

text: string;

134

}

135

136

interface ByteChunk {

137

/** Binary data encoding mode */

138

type: Mode.Byte | Mode.Kanji;

139

/** Raw byte data as numeric array */

140

bytes: number[];

141

/** Decoded text content (may be empty string if decoding fails) */

142

text: string;

143

}

144

145

interface ECIChunk {

146

/** Extended Channel Interpretation mode */

147

type: Mode.ECI;

148

/** ECI assignment number for character encoding */

149

assignmentNumber: number;

150

}

151

152

enum Mode {

153

/** Numeric digits 0-9 */

154

Numeric = "numeric",

155

/** Alphanumeric characters (0-9, A-Z, space, $, %, *, +, -, ., /, :) */

156

Alphanumeric = "alphanumeric",

157

/** 8-bit byte data */

158

Byte = "byte",

159

/** Kanji characters (Shift JIS encoding) */

160

Kanji = "kanji",

161

/** Extended Channel Interpretation for character encoding */

162

ECI = "eci"

163

}

164

```

165

166

## Usage Examples

167

168

### Basic QR Code Scanning

169

170

```javascript

171

import jsQR from "jsqr";

172

173

// From canvas element

174

const canvas = document.getElementById('canvas');

175

const context = canvas.getContext('2d');

176

const imageData = context.getImageData(0, 0, canvas.width, canvas.height);

177

178

const code = jsQR(imageData.data, imageData.width, imageData.height);

179

if (code) {

180

console.log("QR Code found:", code.data);

181

}

182

```

183

184

### Webcam QR Code Scanning

185

186

```javascript

187

import jsQR from "jsqr";

188

189

// In a video frame processing loop

190

function tick() {

191

if (video.readyState === video.HAVE_ENOUGH_DATA) {

192

canvas.width = video.videoWidth;

193

canvas.height = video.videoHeight;

194

context.drawImage(video, 0, 0, canvas.width, canvas.height);

195

196

const imageData = context.getImageData(0, 0, canvas.width, canvas.height);

197

const code = jsQR(imageData.data, imageData.width, imageData.height);

198

199

if (code) {

200

console.log("Found QR code:", code.data);

201

// Access location information

202

console.log("Top-left corner:", code.location.topLeftCorner);

203

}

204

}

205

requestAnimationFrame(tick);

206

}

207

```

208

209

### Performance Optimization

210

211

```javascript

212

import jsQR from "jsqr";

213

214

// For better performance, skip inversion attempts if you know your QR codes

215

// are standard black-on-white

216

const code = jsQR(imageData.data, width, height, {

217

inversionAttempts: "dontInvert"

218

});

219

220

// For white-on-dark QR codes, only try inverted

221

const code2 = jsQR(imageData.data, width, height, {

222

inversionAttempts: "onlyInvert"

223

});

224

```

225

226

### Accessing Detailed Information

227

228

```javascript

229

import jsQR from "jsqr";

230

231

const code = jsQR(imageData.data, width, height);

232

if (code) {

233

console.log("Decoded text:", code.data);

234

console.log("Raw bytes:", code.binaryData);

235

console.log("QR version:", code.version);

236

237

// Access encoding chunks

238

code.chunks.forEach((chunk, index) => {

239

console.log(`Chunk ${index}:`, chunk.type);

240

if (chunk.type === "byte" || chunk.type === "kanji") {

241

console.log("Raw bytes:", chunk.bytes);

242

console.log("Decoded text:", chunk.text);

243

} else if (chunk.type === "eci") {

244

console.log("ECI assignment:", chunk.assignmentNumber);

245

} else {

246

console.log("Text:", chunk.text);

247

}

248

});

249

250

// Draw detection outline on canvas

251

const corners = [

252

code.location.topLeftCorner,

253

code.location.topRightCorner,

254

code.location.bottomRightCorner,

255

code.location.bottomLeftCorner

256

];

257

258

context.strokeStyle = "red";

259

context.beginPath();

260

corners.forEach((corner, index) => {

261

if (index === 0) {

262

context.moveTo(corner.x, corner.y);

263

} else {

264

context.lineTo(corner.x, corner.y);

265

}

266

});

267

context.closePath();

268

context.stroke();

269

}

270

```