2424import java .util .concurrent .Executors ;
2525import 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.\n Currently 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 );
0 commit comments