or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdexperimental-writing.mdimage-processing.mdindex.mdlegacy-writing.mdreading.mdresult-processing.md

legacy-writing.mddocs/

0

# Legacy Barcode Writing

1

2

ZXing-C++ provides barcode generation capabilities through the legacy `MultiFormatWriter` API. This stable API supports the most common barcode formats with essential configuration options, generating barcodes as `BitMatrix` objects that can be converted to various image formats.

3

4

## MultiFormatWriter Class

5

6

The `MultiFormatWriter` class provides a simple interface for generating barcodes:

7

8

```cpp { .api }

9

class MultiFormatWriter {

10

explicit MultiFormatWriter(BarcodeFormat format);

11

12

// Configuration methods

13

MultiFormatWriter& setEncoding(CharacterSet encoding);

14

MultiFormatWriter& setEccLevel(int level);

15

MultiFormatWriter& setMargin(int margin);

16

17

// Generation methods

18

BitMatrix encode(const std::wstring& contents, int width, int height) const;

19

BitMatrix encode(const std::string& contents, int width, int height) const;

20

};

21

```

22

23

## BitMatrix Class

24

25

The `BitMatrix` class represents the generated barcode as a 2D binary matrix:

26

27

```cpp { .api }

28

class BitMatrix {

29

int width() const;

30

int height() const;

31

bool get(int x, int y) const;

32

void set(int x, int y, bool value);

33

34

// Iterator support and utility methods available

35

};

36

```

37

38

## Supported Formats

39

40

The legacy writer supports these formats:

41

42

- **Linear Formats**: Code 39, Code 93, Code 128, Codabar, EAN-8, EAN-13, ITF, UPC-A, UPC-E

43

- **Matrix Formats**: Aztec, DataMatrix, PDF417, QR Code

44

45

## Basic Usage

46

47

### Simple Barcode Generation

48

49

```cpp

50

#include "ZXing/MultiFormatWriter.h"

51

#include "ZXing/BitMatrix.h"

52

53

// Create QR Code

54

auto writer = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::QRCode);

55

auto matrix = writer.encode("Hello, World!", 300, 300);

56

57

// Check dimensions

58

std::cout << "Generated " << matrix.width() << "x" << matrix.height()

59

<< " barcode" << std::endl;

60

61

// Access individual pixels

62

for (int y = 0; y < matrix.height(); ++y) {

63

for (int x = 0; x < matrix.width(); ++x) {

64

bool isBlack = matrix.get(x, y);

65

// Convert to your image format...

66

}

67

}

68

```

69

70

### Configured Generation

71

72

```cpp

73

// Create Code 128 with custom settings

74

auto writer = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::Code128)

75

.setEncoding(ZXing::CharacterSet::UTF8)

76

.setMargin(20); // 20-pixel quiet zone

77

78

auto matrix = writer.encode("ABC123", 400, 100);

79

```

80

81

## Format-Specific Configuration

82

83

### QR Code Generation

84

85

```cpp

86

// QR Code with error correction and encoding

87

auto qrWriter = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::QRCode)

88

.setEncoding(ZXing::CharacterSet::UTF8)

89

.setEccLevel(2) // Error correction level (0-8)

90

.setMargin(10); // Quiet zone margin

91

92

// Generate QR code for URL

93

auto urlMatrix = qrWriter.encode("https://example.com", 200, 200);

94

95

// Generate QR code for text with special characters

96

auto textMatrix = qrWriter.encode("Hello, 世界! 🌍", 250, 250);

97

98

// Generate QR code for structured data

99

std::string vCard = "BEGIN:VCARD\n"

100

"VERSION:3.0\n"

101

"FN:John Doe\n"

102

"ORG:Example Corp\n"

103

"TEL:+1-555-123-4567\n"

104

"EMAIL:john@example.com\n"

105

"END:VCARD";

106

auto vcardMatrix = qrWriter.encode(vCard, 300, 300);

107

```

108

109

### Linear Barcode Generation

110

111

```cpp

112

// Code 128 for alphanumeric data

113

auto code128Writer = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::Code128)

114

.setMargin(15);

115

116

auto code128Matrix = code128Writer.encode("ABC123XYZ", 400, 80);

117

118

// EAN-13 for product codes

119

auto eanWriter = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::EAN13)

120

.setMargin(10);

121

122

// EAN-13 requires exactly 12 digits (13th is check digit)

123

auto eanMatrix = eanWriter.encode("123456789012", 300, 100);

124

125

// UPC-A for US retail

126

auto upcWriter = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::UPCA)

127

.setMargin(10);

128

129

// UPC-A requires exactly 11 digits (12th is check digit)

130

auto upcMatrix = upcWriter.encode("12345678901", 300, 100);

131

```

132

133

### DataMatrix Generation

134

135

```cpp

136

// DataMatrix for small data encoding

137

auto dmWriter = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::DataMatrix)

138

.setEncoding(ZXing::CharacterSet::UTF8)

139

.setMargin(5);

140

141

// Compact data encoding

142

auto dmMatrix = dmWriter.encode("ID:12345", 100, 100);

143

144

// Larger data with text

145

std::string productInfo = "Product: Widget\nSKU: W12345\nDate: 2024-01-15";

146

auto productMatrix = dmWriter.encode(productInfo, 150, 150);

147

```

148

149

### PDF417 Generation

150

151

```cpp

152

// PDF417 for high-capacity data

153

auto pdf417Writer = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::PDF417)

154

.setEncoding(ZXing::CharacterSet::UTF8)

155

.setEccLevel(4) // Error correction level

156

.setMargin(10);

157

158

// Large text document

159

std::string document = "This is a longer document that can contain "

160

"multiple lines of text with various special "

161

"characters and symbols: !@#$%^&*()";

162

auto docMatrix = pdf417Writer.encode(document, 400, 200);

163

```

164

165

## BitMatrix to Image Conversion

166

167

### Manual Conversion

168

169

```cpp

170

// Convert BitMatrix to raw image data

171

std::vector<uint8_t> convertToImage(const ZXing::BitMatrix& matrix,

172

bool addQuietZone = true) {

173

int width = matrix.width();

174

int height = matrix.height();

175

176

// Add quiet zone if requested

177

int quietZone = addQuietZone ? 20 : 0;

178

int imageWidth = width + 2 * quietZone;

179

int imageHeight = height + 2 * quietZone;

180

181

std::vector<uint8_t> image(imageWidth * imageHeight, 255); // White background

182

183

for (int y = 0; y < height; ++y) {

184

for (int x = 0; x < width; ++x) {

185

if (matrix.get(x, y)) {

186

int imageX = x + quietZone;

187

int imageY = y + quietZone;

188

image[imageY * imageWidth + imageX] = 0; // Black pixel

189

}

190

}

191

}

192

193

return image;

194

}

195

```

196

197

### Scaled Conversion

198

199

```cpp

200

// Convert with scaling for larger output

201

std::vector<uint8_t> convertToScaledImage(const ZXing::BitMatrix& matrix,

202

int scale = 4) {

203

int matrixWidth = matrix.width();

204

int matrixHeight = matrix.height();

205

int imageWidth = matrixWidth * scale;

206

int imageHeight = matrixHeight * scale;

207

208

std::vector<uint8_t> image(imageWidth * imageHeight, 255);

209

210

for (int matrixY = 0; matrixY < matrixHeight; ++matrixY) {

211

for (int matrixX = 0; matrixX < matrixWidth; ++matrixX) {

212

if (matrix.get(matrixX, matrixY)) {

213

// Fill scale x scale block

214

for (int dy = 0; dy < scale; ++dy) {

215

for (int dx = 0; dx < scale; ++dx) {

216

int imageX = matrixX * scale + dx;

217

int imageY = matrixY * scale + dy;

218

image[imageY * imageWidth + imageX] = 0;

219

}

220

}

221

}

222

}

223

}

224

225

return image;

226

}

227

```

228

229

### RGB Conversion

230

231

```cpp

232

// Convert to RGB format

233

std::vector<uint8_t> convertToRGB(const ZXing::BitMatrix& matrix,

234

uint8_t bgR = 255, uint8_t bgG = 255, uint8_t bgB = 255,

235

uint8_t fgR = 0, uint8_t fgG = 0, uint8_t fgB = 0) {

236

int width = matrix.width();

237

int height = matrix.height();

238

std::vector<uint8_t> rgb(width * height * 3);

239

240

for (int y = 0; y < height; ++y) {

241

for (int x = 0; x < width; ++x) {

242

int idx = (y * width + x) * 3;

243

if (matrix.get(x, y)) {

244

rgb[idx] = fgR; // Red

245

rgb[idx + 1] = fgG; // Green

246

rgb[idx + 2] = fgB; // Blue

247

} else {

248

rgb[idx] = bgR; // Red

249

rgb[idx + 1] = bgG; // Green

250

rgb[idx + 2] = bgB; // Blue

251

}

252

}

253

}

254

255

return rgb;

256

}

257

```

258

259

## Integration Examples

260

261

### Using with STB Image Write

262

263

```cpp

264

#define STB_IMAGE_WRITE_IMPLEMENTATION

265

#include <stb_image_write.h>

266

267

void saveBarcodeAsPNG(const ZXing::BitMatrix& matrix, const std::string& filename) {

268

auto imageData = convertToScaledImage(matrix, 4);

269

int width = matrix.width() * 4;

270

int height = matrix.height() * 4;

271

272

stbi_write_png(filename.c_str(), width, height, 1, imageData.data(), width);

273

}

274

275

// Usage

276

auto writer = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::QRCode);

277

auto matrix = writer.encode("Hello, World!", 200, 200);

278

saveBarcodeAsPNG(matrix, "qrcode.png");

279

```

280

281

### Using with OpenCV

282

283

```cpp

284

#include <opencv2/opencv.hpp>

285

286

cv::Mat convertToCvMat(const ZXing::BitMatrix& matrix) {

287

int width = matrix.width();

288

int height = matrix.height();

289

cv::Mat image(height, width, CV_8UC1, cv::Scalar(255));

290

291

for (int y = 0; y < height; ++y) {

292

for (int x = 0; x < width; ++x) {

293

if (matrix.get(x, y)) {

294

image.at<uint8_t>(y, x) = 0;

295

}

296

}

297

}

298

299

return image;

300

}

301

302

// Usage

303

auto writer = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::Code128);

304

auto matrix = writer.encode("CODE128", 400, 100);

305

cv::Mat image = convertToCvMat(matrix);

306

cv::imwrite("code128.png", image);

307

```

308

309

## Error Handling

310

311

### Invalid Parameters

312

313

```cpp

314

try {

315

auto writer = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::EAN13);

316

317

// This will fail - EAN13 requires exactly 12 digits

318

auto matrix = writer.encode("123", 300, 100);

319

320

} catch (const std::exception& e) {

321

std::cout << "Generation failed: " << e.what() << std::endl;

322

}

323

```

324

325

### Format Validation

326

327

```cpp

328

bool validateContentForFormat(const std::string& content, ZXing::BarcodeFormat format) {

329

switch (format) {

330

case ZXing::BarcodeFormat::EAN13:

331

return content.length() == 12 &&

332

std::all_of(content.begin(), content.end(), ::isdigit);

333

334

case ZXing::BarcodeFormat::UPCA:

335

return content.length() == 11 &&

336

std::all_of(content.begin(), content.end(), ::isdigit);

337

338

case ZXing::BarcodeFormat::Code39:

339

// Code39 supports A-Z, 0-9, and special characters

340

return std::all_of(content.begin(), content.end(), [](char c) {

341

return std::isalnum(c) ||

342

c == '-' || c == '.' || c == ' ' || c == '*' ||

343

c == '$' || c == '/' || c == '+' || c == '%';

344

});

345

346

default:

347

return true; // Most formats accept arbitrary strings

348

}

349

}

350

351

// Usage

352

std::string content = "123456789012";

353

if (validateContentForFormat(content, ZXing::BarcodeFormat::EAN13)) {

354

auto writer = ZXing::MultiFormatWriter(ZXing::BarcodeFormat::EAN13);

355

auto matrix = writer.encode(content, 300, 100);

356

}

357

```

358

359

## Advanced Usage

360

361

### Batch Generation

362

363

```cpp

364

class BarcodeGenerator {

365

private:

366

std::map<ZXing::BarcodeFormat, ZXing::MultiFormatWriter> writers_;

367

368

public:

369

BarcodeGenerator() {

370

// Pre-configure writers for different formats

371

writers_.emplace(ZXing::BarcodeFormat::QRCode,

372

ZXing::MultiFormatWriter(ZXing::BarcodeFormat::QRCode)

373

.setEncoding(ZXing::CharacterSet::UTF8)

374

.setEccLevel(2)

375

.setMargin(10));

376

377

writers_.emplace(ZXing::BarcodeFormat::Code128,

378

ZXing::MultiFormatWriter(ZXing::BarcodeFormat::Code128)

379

.setMargin(15));

380

}

381

382

ZXing::BitMatrix generate(const std::string& content,

383

ZXing::BarcodeFormat format,

384

int width, int height) {

385

auto it = writers_.find(format);

386

if (it != writers_.end()) {

387

return it->second.encode(content, width, height);

388

}

389

390

// Fallback to default configuration

391

auto writer = ZXing::MultiFormatWriter(format);

392

return writer.encode(content, width, height);

393

}

394

};

395

396

// Usage for batch processing

397

BarcodeGenerator generator;

398

std::vector<std::string> products = {"12345", "67890", "ABCDE"};

399

400

for (const auto& product : products) {

401

auto matrix = generator.generate(product, ZXing::BarcodeFormat::Code128, 400, 80);

402

// Save or process matrix...

403

}

404

```

405

406

### Size Optimization

407

408

```cpp

409

// Find optimal size for content

410

std::pair<int, int> findOptimalSize(const std::string& content,

411

ZXing::BarcodeFormat format) {

412

auto writer = ZXing::MultiFormatWriter(format);

413

414

// Try different sizes to find minimum

415

std::vector<std::pair<int, int>> sizes = {

416

{100, 100}, {150, 150}, {200, 200}, {250, 250}, {300, 300}

417

};

418

419

for (const auto& size : sizes) {

420

try {

421

auto matrix = writer.encode(content, size.first, size.second);

422

return {matrix.width(), matrix.height()};

423

} catch (...) {

424

continue;

425

}

426

}

427

428

return {300, 300}; // Default fallback

429

}

430

```