Skip to content

Commit 1a68f39

Browse files
committed
Support Dynamsoft Barcode Reader
1 parent 3299d3e commit 1a68f39

5 files changed

Lines changed: 126 additions & 18 deletions

File tree

Binary file not shown.
Binary file not shown.
0 Bytes
Binary file not shown.

examples/barcode-scanner/maven-example/src/main/java/com/example/litecam/BarcodeScanner.java

Lines changed: 104 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@
2424
import java.util.concurrent.Executors;
2525
import java.util.concurrent.atomic.AtomicBoolean;
2626

27+
import com.dynamsoft.core.EnumErrorCode;
28+
import com.dynamsoft.core.EnumImagePixelFormat;
29+
import com.dynamsoft.cvr.CaptureVisionRouter;
30+
import com.dynamsoft.cvr.CapturedResult;
31+
import com.dynamsoft.cvr.EnumPresetTemplate;
32+
import com.dynamsoft.dbr.BarcodeResultItem;
33+
import com.dynamsoft.dbr.DecodedBarcodesResult;
34+
import com.dynamsoft.license.LicenseError;
35+
import com.dynamsoft.license.LicenseException;
36+
import com.dynamsoft.license.LicenseManager;
37+
import com.dynamsoft.core.basic_structures.ImageData;
38+
import com.dynamsoft.core.basic_structures.Quadrilateral;
39+
2740
/**
2841
* Enhanced LiteCam Barcode Scanner with ZXing integration and visual overlays
2942
* Supports both camera and file modes with proper threading architecture
@@ -34,10 +47,10 @@ public class BarcodeScanner extends JPanel {
3447
// Inner class to hold detected barcode information
3548
private static class DetectedBarcode {
3649
final String text;
37-
final BarcodeFormat format;
50+
final String format;
3851
final ResultPoint[] resultPoints;
3952

40-
DetectedBarcode(String text, BarcodeFormat format, ResultPoint[] resultPoints) {
53+
DetectedBarcode(String text, String format, ResultPoint[] resultPoints) {
4154
this.text = text;
4255
this.format = format;
4356
this.resultPoints = resultPoints;
@@ -81,6 +94,7 @@ public String toString() {
8194
private Timer frameTimer;
8295

8396
// Barcode detection components
97+
private CaptureVisionRouter cvRouter;
8498
private MultiFormatReader zxingReader;
8599
private GenericMultipleBarcodeReader multiReader;
86100
private ScannerType currentScannerType = ScannerType.ZXING;
@@ -139,6 +153,7 @@ public BarcodeScanner() {
139153
private void initializeBarcodeReaders() {
140154
// Initialize ZXing
141155
try {
156+
cvRouter = new CaptureVisionRouter();
142157
zxingReader = new MultiFormatReader();
143158
multiReader = new GenericMultipleBarcodeReader(zxingReader);
144159
logger.info("ZXing initialized successfully with multiple barcode support");
@@ -350,15 +365,6 @@ private void onScannerChanged(ActionEvent e) {
350365
if (newType != currentScannerType) {
351366
currentScannerType = newType;
352367
logger.info("Scanner changed to: {}", currentScannerType);
353-
354-
if (currentScannerType == ScannerType.DYNAMSOFT) {
355-
JOptionPane.showMessageDialog(this,
356-
"Dynamsoft Barcode Reader is not yet implemented.\nCurrently using ZXing.",
357-
"Scanner Not Available", JOptionPane.INFORMATION_MESSAGE);
358-
// Reset to ZXing
359-
currentScannerType = ScannerType.ZXING;
360-
scannerDropdown.setSelectedItem(ScannerType.ZXING);
361-
}
362368
}
363369
}
364370

@@ -533,14 +539,74 @@ private List<DetectedBarcode> detectBarcodes(BufferedImage image) {
533539
case ZXING:
534540
return detectWithZXing(image);
535541
case DYNAMSOFT:
536-
// Placeholder for Dynamsoft - for now, fallback to ZXing
537-
logger.warn("Dynamsoft not implemented, falling back to ZXing");
538-
return detectWithZXing(image);
542+
return detectWithDBR(image);
539543
default:
540544
return detections;
541545
}
542546
}
543547

548+
private List<DetectedBarcode> detectWithDBR(BufferedImage image) {
549+
List<DetectedBarcode> detections = new ArrayList<>();
550+
551+
if (image == null || cvRouter == null)
552+
return detections;
553+
554+
try {
555+
// Convert BufferedImage to byte array for Dynamsoft
556+
int width = image.getWidth();
557+
int height = image.getHeight();
558+
559+
// Convert to RGB format
560+
BufferedImage rgbImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
561+
Graphics2D g2d = rgbImage.createGraphics();
562+
g2d.drawImage(image, 0, 0, null);
563+
g2d.dispose();
564+
565+
// Get byte array from image
566+
byte[] imageBytes = ((java.awt.image.DataBufferByte) rgbImage.getRaster().getDataBuffer()).getData();
567+
568+
// Create ImageData object for Dynamsoft - use reflection to find correct
569+
// constructor
570+
ImageData imageData = new ImageData(imageBytes, width, height, width * 3, EnumImagePixelFormat.IPF_RGB_888,
571+
0, null);
572+
573+
// Capture barcodes using ImageData
574+
CapturedResult result = cvRouter.capture(imageData, EnumPresetTemplate.PT_READ_BARCODES);
575+
DecodedBarcodesResult barcodeResult = result != null ? result.getDecodedBarcodesResult() : null;
576+
BarcodeResultItem[] items = barcodeResult != null ? barcodeResult.getItems() : null;
577+
578+
if (items != null) {
579+
for (int i = 0; i < items.length; i++) {
580+
BarcodeResultItem item = items[i];
581+
582+
// Convert Dynamsoft location to ZXing ResultPoint format
583+
Quadrilateral location = item.getLocation();
584+
com.dynamsoft.core.basic_structures.Point[] dbrPoints = location.points;
585+
586+
// Create ZXing-compatible result points
587+
ResultPoint[] resultPoints = new ResultPoint[dbrPoints.length];
588+
for (int j = 0; j < dbrPoints.length; j++) {
589+
float x = (float) dbrPoints[j].getX();
590+
float y = (float) dbrPoints[j].getY();
591+
resultPoints[j] = new ResultPoint(x, y);
592+
}
593+
594+
// Create detection and add to list
595+
DetectedBarcode detection = new DetectedBarcode(
596+
item.getText(),
597+
item.getFormatString(),
598+
resultPoints);
599+
detections.add(detection);
600+
}
601+
}
602+
603+
} catch (Exception e) {
604+
logger.error("DBR detection failed: {}", e.getMessage());
605+
}
606+
607+
return detections;
608+
}
609+
544610
private List<DetectedBarcode> detectWithZXing(BufferedImage image) {
545611
List<DetectedBarcode> detections = new ArrayList<>();
546612

@@ -557,7 +623,7 @@ private List<DetectedBarcode> detectWithZXing(BufferedImage image) {
557623
for (Result result : results) {
558624
DetectedBarcode detection = new DetectedBarcode(
559625
result.getText(),
560-
result.getBarcodeFormat(),
626+
result.getBarcodeFormat().toString(),
561627
result.getResultPoints());
562628
detections.add(detection);
563629
}
@@ -573,7 +639,7 @@ private List<DetectedBarcode> detectWithZXing(BufferedImage image) {
573639
Result result = zxingReader.decode(bitmap);
574640
DetectedBarcode detection = new DetectedBarcode(
575641
result.getText(),
576-
result.getBarcodeFormat(),
642+
result.getBarcodeFormat().toString(),
577643
result.getResultPoints());
578644
detections.add(detection);
579645
} catch (NotFoundException e) {
@@ -589,8 +655,9 @@ private List<DetectedBarcode> detectWithZXing(BufferedImage image) {
589655

590656
private void updateResultsDisplay(List<DetectedBarcode> detections) {
591657
for (DetectedBarcode detection : detections) {
592-
String barcodeInfo = String.format("[ZXing] %s (%s)",
593-
detection.text, detection.format);
658+
String scannerType = currentScannerType == ScannerType.ZXING ? "ZXing" : "Dynamsoft";
659+
String barcodeInfo = String.format("[%s] %s (%s)",
660+
scannerType, detection.text, detection.format);
594661

595662
if (!scannedResults.contains(barcodeInfo)) {
596663
scannedResults.add(barcodeInfo);
@@ -858,6 +925,25 @@ private void loadImageFromFile(File file) {
858925
}
859926

860927
public static void main(String[] args) {
928+
int errorCode = 0;
929+
String errorMsg = "";
930+
931+
try {
932+
LicenseError licenseError = LicenseManager.initLicense(
933+
"DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==");
934+
if (licenseError.getErrorCode() != EnumErrorCode.EC_OK) {
935+
errorCode = licenseError.getErrorCode();
936+
errorMsg = licenseError.getErrorString();
937+
}
938+
} catch (LicenseException e) {
939+
errorCode = e.getErrorCode();
940+
errorMsg = e.getErrorString();
941+
}
942+
943+
if (errorCode != EnumErrorCode.EC_OK) {
944+
System.out.println("License initialization failed: ErrorCode: " + errorCode + ", ErrorString: " + errorMsg);
945+
}
946+
861947
SwingUtilities.invokeLater(() -> {
862948
JFrame frame = new JFrame("LiteCam Barcode Scanner");
863949
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# PowerShell script to run LiteCam Java Viewer
2+
param([string[]]$Args = @())
3+
4+
$ErrorActionPreference = 'Stop'
5+
6+
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
7+
$jarPath = Join-Path $scriptDir 'litecam.jar'
8+
9+
if (-not (Test-Path $jarPath)) {
10+
Write-Host "Error: litecam.jar not found in $scriptDir" -ForegroundColor Red
11+
Write-Host "Please run build-jar.ps1 first to build the JAR file." -ForegroundColor Yellow
12+
exit 1
13+
}
14+
15+
try {
16+
Write-Host "Starting LiteCam Java Viewer..." -ForegroundColor Green
17+
& java -cp $jarPath com.example.litecam.LiteCamViewer @Args
18+
} catch {
19+
Write-Host "Error: Failed to run LiteCam Java Viewer: $($_.Exception.Message)" -ForegroundColor Red
20+
Write-Host "Make sure Java is installed and accessible from PATH." -ForegroundColor Yellow
21+
exit 1
22+
}

0 commit comments

Comments
 (0)