<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eric Parker 🥂</title>
    <description>The latest articles on DEV Community by Eric Parker 🥂 (@iamparkereric).</description>
    <link>https://dev.to/iamparkereric</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F985058%2Fdaea1660-9081-4288-911a-53f915928968.jpg</url>
      <title>DEV Community: Eric Parker 🥂</title>
      <link>https://dev.to/iamparkereric</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iamparkereric"/>
    <language>en</language>
    <item>
      <title>How to Auto-Deploy Source Code to Web Server via Webhook</title>
      <dc:creator>Eric Parker 🥂</dc:creator>
      <pubDate>Mon, 29 Jan 2024 05:41:49 +0000</pubDate>
      <link>https://dev.to/iamparkereric/how-to-auto-deploy-source-code-to-web-server-via-webhook-3073</link>
      <guid>https://dev.to/iamparkereric/how-to-auto-deploy-source-code-to-web-server-via-webhook-3073</guid>
      <description>&lt;p&gt;If you use GitHub to manage the source code of your website, you can utilize webhooks to transmit GitHub events to third-party services. In this article, we will explore how to deploy a website to IIS, as well as how to pull the source code and automatically update the site when a push event occurs. &lt;/p&gt;

&lt;h2&gt;
  
  
  IIS Configuration in Windows 10
&lt;/h2&gt;

&lt;p&gt;To activate IIS, go to the "Windows features" menu. By default, all "Application Development Features" are turned off. Choose the necessary features. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvk57ipomdk5t4091hxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvk57ipomdk5t4091hxx.png" alt="Configure IIS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use Visual C# to Handle HTTP Request
&lt;/h2&gt;

&lt;p&gt;In Visual Studio, create an empty ASP.NET web application. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6nnqy27yhn9pfhxrszj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6nnqy27yhn9pfhxrszj.png" alt="ASP.net application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create an HTML file called index.htm. &lt;br&gt;
Webhook.ashx should have a generic handler. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63qz349s0pinyhzqcm8h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63qz349s0pinyhzqcm8h.png" alt="Webhook generic handler"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Publish the project. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhok0qwlfqkfe2oa15ld.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhok0qwlfqkfe2oa15ld.png" alt="Publish Project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select IIS &amp;gt; File System. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjb3he0fn8j7j9dun503u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjb3he0fn8j7j9dun503u.png" alt="Selecting IIS file system"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To add the website, launch IIS. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figgf96a3b8alkjiibeul.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figgf96a3b8alkjiibeul.png" alt="Launch IIS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see if the URL works in your web browser, go to &lt;a href="http://localhost/Webhook.ashx" rel="noopener noreferrer"&gt;http://localhost/Webhook.ashx&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjhmj42cc6stdjbumjn0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjhmj42cc6stdjbumjn0.png" alt="Webhook browser URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following step is to execute the git pull command in C#. We can refer to the CodeProject sample code. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5umkptezs5t7ysgjm5mj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5umkptezs5t7ysgjm5mj.png" alt="Codeproject sample code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A batch file to execute required commands.: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;batchFile = Path.Combine(context.Server.MapPath("."), "github.bat"); &lt;br&gt;
objThread.Start(batchFile);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The physical path of the project is &lt;strong&gt;d:\iis&lt;/strong&gt;, so the &lt;strong&gt;github.bat&lt;/strong&gt; is as follows: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;d: &lt;br&gt;
cd d:\\iis &lt;br&gt;
git pull&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Expose the Local Web Server to the Internet
&lt;/h2&gt;

&lt;p&gt;We must give a proper URL to use GitHub webhooks. Ngrok is an excellent tool for connecting a local webserver to the internet. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;ngrok http 80&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feayc591ifalxn3gfv53t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feayc591ifalxn3gfv53t.png" alt="Connect local server to internet"&gt;&lt;/a&gt;&lt;br&gt;
The webhook URL is now &lt;a href="https://048dab0c.ngrok.io/Webhook.ashx" rel="noopener noreferrer"&gt;https://048dab0c.ngrok.io/Webhook.ashx&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use GitHub Webhook to Trigger the Auto-Deployment
&lt;/h2&gt;

&lt;p&gt;Once the URL is complete, we may create a new GitHub repository. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pbwdsqyfltzph3ael04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pbwdsqyfltzph3ael04.png" alt="Create github repository"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;d:\iis&lt;/code&gt; to the remote repository and push it. &lt;/p&gt;

&lt;p&gt;To add the payload URL, go to &lt;code&gt;Settings &amp;gt; Webhooks and enter&lt;/code&gt;: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwnn8cnlmfegbais2d2z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwnn8cnlmfegbais2d2z.png" alt="Add payload URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clone the repository to a new location or another computer. Make some changes to the index.html file and commit them to GitHub. &lt;/p&gt;

&lt;p&gt;The web server will immediately receive an HTTP request and execute the 'git pull' operation. &lt;/p&gt;

&lt;p&gt;To see the update, refresh the website &lt;a href="https://048dab0c.ngrok.io/" rel="noopener noreferrer"&gt;https://048dab0c.ngrok.io/&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>github</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Annotate Barcode Object with LabelImg for Machine Learning</title>
      <dc:creator>Eric Parker 🥂</dc:creator>
      <pubDate>Tue, 26 Sep 2023 07:17:52 +0000</pubDate>
      <link>https://dev.to/iamparkereric/how-to-annotate-barcode-object-with-labelimg-for-machine-learning-4fec</link>
      <guid>https://dev.to/iamparkereric/how-to-annotate-barcode-object-with-labelimg-for-machine-learning-4fec</guid>
      <description>&lt;p&gt;LabelImg is a Python and Qt5-based image annotation tool that's both free and open-source. It's compatible with popular machine learning frameworks like Pascal VOC and Yolo formats. If you're keen on barcode object detection, you can employ this tool to annotate various barcode symbologies using bounding boxes. In this article, I'll demonstrate how to efficiently acquire multiple barcode images from Google and leverage the &lt;a href="https://www.dynamsoft.com/barcode-reader/overview/"&gt;Dynamsoft Barcode Reader SDK&lt;/a&gt; to automate the process of assigning label names. &lt;/p&gt;

&lt;h2&gt;
  
  
  Image Download
&lt;/h2&gt;

&lt;p&gt;To begin, we require images. &lt;em&gt;How can we obtain a collection of images categorized under the same classification?&lt;/em&gt; Fortunately, there's a handy Python library known as "google_images_download" for this purpose. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install google_images_download&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;While utilizing the library, I encountered an issue where it consistently failed to download images, rendering it non-functional. This problem has been discussed on &lt;a href="https://github.com/hardikvasa/google-images-download/issues/331"&gt;https://github.com/hardikvasa/google-images-download/issues/331&lt;/a&gt;. Fortunately, a helpful workaround has been offered. We can opt for a forked repository that has successfully addressed the issue: &lt;/p&gt;

&lt;p&gt;git clone &lt;a href="https://github.com/Joeclinton1/google-images-download.git"&gt;https://github.com/Joeclinton1/google-images-download.git&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd google-images-download &amp;amp;&amp;amp; python setup.py install&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;A straightforward Python script can be employed to retrieve images, as demonstrated below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from google_images_download import google_images_download   
import argparse 


ap = argparse.ArgumentParser() 
ap.add_argument("-k", "--keywords", required=True, 
    help="The keywords/key phrases you want to search for.") 
ap.add_argument("-l", "--limit", required=True, 
    help="The number of images that you want to download.") 
args = vars(ap.parse_args()) 

response = google_images_download.googleimagesdownload() 
arguments = {"keywords":args\["keywords"\],"limit":args\["limit"\],"print_urls":True}   
paths = response.download(arguments) 
print(paths)  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the Python script as "&lt;code&gt;google-image-downloader.py.&lt;/code&gt;" Now, let's proceed to download ten PDF417 images from Google: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;python3 google-image-downloader.py -k pdf417 -l 10&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Barcode Object Annotation
&lt;/h2&gt;

&lt;p&gt;With the barcode images prepared, we can commence the process of labelling them. Our initial step involves obtaining the source code from the LabelImg repository: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone https://github.com/tzutalin/labelImg.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;LabelImg enables us to manually label various objects visually, but when it comes to less familiar barcode symbologies, this method may not be optimal. To efficiently and accurately name barcode objects, we can employ Dynamsoft Barcode Reader as a supplementary tool: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install dbr&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Setting up Dynamsoft Barcode Reader is a straightforward process: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;from dbr import * &lt;br&gt;
reader = BarcodeReader()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the "&lt;code&gt;newShape(self)&lt;/code&gt;" function within &lt;code&gt;labelImg.py&lt;/code&gt;. This function is invoked upon completing the drawing of a bounding box for an object. Subsequently, our next task is to retrieve the coordinates from the current shape, which is stored as the last element within a shape array in the canvas: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;shape = self.canvas.shapes[-1]&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Each shape consists of four points. To obtain the coordinate values and define the region values for Dynamsoft Barcode Reader, we focus on the top-left point and the bottom-right point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;reader.reset_runtime_settings() 
shape = self.canvas.shapes[-1] 
points = shape.points 
settings = reader.get_runtime_settings() 
settings.region_bottom  = round(points[2].y()) 
settings.region_left    = round(points[0].x()) 
settings.region_right   = round(points[2].x()) 
settings.region_top     = round(points[0].y()) 
reader.update_runtime_settings(settings) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following this, we can access the barcode information within the specified region by calling the Python barcode decoding API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try: 

  text_results = reader.decode_file(self.filePath) 

    if text_results != None: 

      for text_result in text_results: 

          print("Barcode Format :") 

          print(text_result.barcode_format_string) 

          self.prevLabelText = text_result.barcode_format_string 

          print("Barcode Text :") 

          print(text_result.barcode_text) 

          print("Localization Points : ") 

          print(text_result.localization_result.localization_points) 

          print("-------------") 

except BarcodeReaderError as bre: 

    print(bre) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the labelImg.py file and execute the program: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;python3 labelImg.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When you draw a rectangular box around a barcode object, it will automatically populate the label dialog with the relevant &lt;a href="https://www.dynamsoft.com/barcode-reader/barcode-types/"&gt;barcode type&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZiNnETXT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xiwxkx6o9mcswdvo5zdq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZiNnETXT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xiwxkx6o9mcswdvo5zdq.png" alt="labelimg barcode annotation" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Running and Debugging a Python Barcode App in Docker Container</title>
      <dc:creator>Eric Parker 🥂</dc:creator>
      <pubDate>Wed, 16 Aug 2023 09:55:38 +0000</pubDate>
      <link>https://dev.to/iamparkereric/running-and-debugging-a-python-barcode-app-in-docker-container-b4k</link>
      <guid>https://dev.to/iamparkereric/running-and-debugging-a-python-barcode-app-in-docker-container-b4k</guid>
      <description>&lt;p&gt;When creating Python barcode extensions using CPython and Dynamsoft Barcode reader, one of the major concerns you have to face is to test your code compatibility with different versions of Python. &lt;/p&gt;

&lt;p&gt;To test if your Python barcode extension works in your Windows, Linux or macOS you will need to have each version of Python installed on your computer. However, it’s time consuming. &lt;/p&gt;

&lt;p&gt;Here, we have an easy hack for you! Instead of installing all those Python versions, you can use Docker container.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Docker Image with Python Barcode SDK
&lt;/h2&gt;

&lt;p&gt;First of all, download Docker desktop and install it.  &lt;/p&gt;

&lt;p&gt;If your system does not have Python 3.8, then go to Docker hub and pull out a Docker image that contains Python 3.8. Now invoke the command from the command prompt: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -it --rm python:3.8 bash&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;If the docker image does not exist, the command given above will by itself trigger the download. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--liwqNhjo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vzmdpjvqxtoh31qz87zz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--liwqNhjo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vzmdpjvqxtoh31qz87zz.png" alt="Create Docker Image" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next you can create a Dockerfile to create a fresh Docker image that will include the &lt;a href="https://www.dynamsoft.com/barcode-reader/overview/"&gt;Dynamsoft Barcode Reader SDK&lt;/a&gt;: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;FROM python:3.8 &lt;br&gt;
RUN pip install dbr&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To generate a Docker image: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build --rm -t yushulx/dynamsoft-barcode-reader:python-3.8&lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;Further run a container test. It will help you validate if your Python based Dynamsoft Barcode Reader is working fine or not.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -it --rm yushulx/dynamsoft-barcode-reader:python-3.8&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LIq6WC1E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9l9b3kjuyn7dtj6miux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LIq6WC1E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9l9b3kjuyn7dtj6miux.png" alt="Validate Python Code" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next you need to publish the Docker Image to your Docker Hub after your container is validated: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker login &lt;br&gt;
docker push yushulx/dynamsoft-barcode-reader:python-3.8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can visit the below given link to test the image:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hub.docker.com/repository/docker/yushulx/dynamsoft-barcode-reader"&gt;https://hub.docker.com/repository/docker/yushulx/dynamsoft-barcode-reader&lt;/a&gt;. &lt;/p&gt;
&lt;h2&gt;
  
  
  Mounting Local Folder to Docker Container
&lt;/h2&gt;

&lt;p&gt;To mount a local Window folder to Linux Docker Container, execute the Python script using Python 3.8. &lt;/p&gt;

&lt;p&gt;After that, select the shared drive from the settings of the Docker desktop: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Kf0za32--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvrvo3720iv1hnz63fwd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Kf0za32--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvrvo3720iv1hnz63fwd.png" alt="Docker Shared Device" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To mount the Windows folder to the Linux container execute the following command: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -it --rm -v d:/code/docker:/dynamsoft yushulx/dynamsoft-barcode-reader:python-3.8  bash&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--agOsAMVq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nddxcnf0yp8xp2f0x3pc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--agOsAMVq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nddxcnf0yp8xp2f0x3pc.png" alt="Execute Linux Command" width="800" height="371"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  How To Debug Python Code with Visual Studio Code Remote-Containers
&lt;/h2&gt;

&lt;p&gt;The preferred option to write and debug the Python code is to use Visual Studio Code. &lt;/p&gt;

&lt;p&gt;To start with it, first install Docker extension for VSCode as shown below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vL7T2oNq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z4xizykoqdmac4h1cekp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vL7T2oNq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z4xizykoqdmac4h1cekp.png" alt="VSCode Extention" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click F1 key to execute the “Attach to Running Container” option. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xv834Q5U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l6qa4igjruuqw7vnkk47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xv834Q5U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l6qa4igjruuqw7vnkk47.png" alt="Running Container" width="747" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Double-click on the project folder. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vf7zJPeB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iapqpdxsgmq2074pskcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vf7zJPeB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iapqpdxsgmq2074pskcn.png" alt="Docker Project" width="747" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JO5V57nj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnkmtucxzuxgdn3bop5e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JO5V57nj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnkmtucxzuxgdn3bop5e.png" alt="Python Project" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will allow you to edit the Python file in VSCode. Next install the Python debugger for the container to debug the code:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3SRuhHA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qd9mn0lxx0jalotvsn0h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3SRuhHA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qd9mn0lxx0jalotvsn0h.png" alt="Install Python Debugger" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For debugging of the code remotely, click F5. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L_mrk0Ax--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5tffrpwderwve3v700vl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L_mrk0Ax--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5tffrpwderwve3v700vl.png" alt="Code Debug" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tLrP_Ayu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kz3upy1v374mqipqb0vw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tLrP_Ayu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kz3upy1v374mqipqb0vw.png" alt="Python Debug" width="800" height="381"&gt;&lt;/a&gt;&lt;br&gt;
The complete Python barcode detection code is given below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os 


from dbr import DynamsoftBarcodeReader 

dbr = DynamsoftBarcodeReader() 




def InitLicense(license): 

    dbr.InitLicense(license) 




def DecodeFile(fileName): 

    try: 

        results = dbr.DecodeFile(fileName) 

        textResults = results["TextResults"] 

        resultsLength = len(textResults) 

        print("count: " + str(resultsLength)) 

        if resultsLength != 0: 

            for textResult in textResults: 

                print(textResult["BarcodeFormatString"]) 

                print(textResult["BarcodeText"]) 

                localizationResult = textResult["LocalizationResult"] 

                x1 = localizationResult["X1"] 

                y1 = localizationResult["Y1"] 

                x2 = localizationResult["X2"] 

                y2 = localizationResult["Y2"] 

                x3 = localizationResult["X3"] 

                y3 = localizationResult["Y3"] 

                x4 = localizationResult["X4"] 

                y4 = localizationResult["Y4"] 

                localizationPoints = [(x1,y1),(x2,y2),(x3,y3),(x4,y4)] 

                print(localizationPoints) 

        else : 

            print("No barcode detected") 

    except Exception as err: 

        print(err) 




if __name__ == "__main__": 

    # Get the license from https://www.dynamsoft.com/customer/license/trialLicense/ 

    licenseKey = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="  

    fileName = r"test.jpg" 

    InitLicense(licenseKey) 

    dir_path = os.path.dirname(os.path.realpath(__file__)) 

    DecodeFile(os.path.join(dir_path, fileName)) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>docker</category>
      <category>containers</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building an Android Barcode Reader: Use Barcode SDK for a successful outcome</title>
      <dc:creator>Eric Parker 🥂</dc:creator>
      <pubDate>Thu, 20 Jul 2023 08:15:24 +0000</pubDate>
      <link>https://dev.to/iamparkereric/building-an-android-barcode-reader-use-barcode-sdk-for-a-successful-outcome-2c61</link>
      <guid>https://dev.to/iamparkereric/building-an-android-barcode-reader-use-barcode-sdk-for-a-successful-outcome-2c61</guid>
      <description>&lt;p&gt;Different options exist when creating a mobile app that can scan barcodes on Android or iOS devices. You can choose between using open-source Software Development Kits (SDKs) like ZXing and ZBar, or you can opt for commercial barcode reading SDKs.&lt;/p&gt;

&lt;p&gt;Commercial barcode reading SDKs deliver much better usability than their open-source counterparts. They offer a well-designed API and quality technical documentation to the developers. Also, ab easy to use SDK means less product launch time, eventually contributing to quicker revenue generation. &lt;/p&gt;

&lt;p&gt;If you're an Android developer and have already installed the Android Play Services SDK version 26 or higher, there's a convenient way to create a barcode scanning app using the Android Vision API. Google has even provided a demo on GitHub that we can use as a reference to build our own barcode reader app for Android.&lt;/p&gt;

&lt;p&gt;Now, let's break down the code and understand how it works to create our own version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Android Barcode Demo with Google Vision API
&lt;/h2&gt;

&lt;p&gt;To begin, you can download the sample code for Android Vision from the following link: &lt;a href="https://github.com/googlesamples/android-vision"&gt;https://github.com/googlesamples/android-vision&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once downloaded, open Android Studio and load the "barcode-reader" folder from the downloaded code.&lt;/p&gt;

&lt;p&gt;Let's find the starting point in the code where we can work with the camera preview data. To do this, you can press &lt;code&gt;Ctrl+Alt+Shift+N&lt;/code&gt; (or use the global search function) in Android Studio. Search for "&lt;code&gt;onPreviewFrame&lt;/code&gt;" in the file named "&lt;code&gt;CameraSource.java&lt;/code&gt;."&lt;/p&gt;

&lt;p&gt;By locating and understanding this part of the code, you can begin exploring how to handle the camera preview and move forward with building our barcode scanning functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private class CameraPreviewCallback implements Camera.PreviewCallback {
    @Override
    public void onPreviewFrame(byte\[\] data, Camera camera) {
        mFrameProcessor.setNextFrame(data, camera);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code, you'll come across an instance called "&lt;code&gt;mFrameProcessor&lt;/code&gt;," which belongs to the &lt;code&gt;FrameProcessingRunnable&lt;/code&gt; class. This instance is responsible for processing the preview data in a separate worker thread. The benefit of using a worker thread is that it prevents the barcode detection API from blocking the user interface (UI) thread, ensuring a smooth user experience.&lt;/p&gt;

&lt;p&gt;Now, let's examine the "&lt;code&gt;setNextFrame&lt;/code&gt;" method, which utilizes synchronization to lock the data. When a frame of preview data is received, it is cached and stored. Then, it notifies the worker thread to start processing and reading the barcode from the cached frame.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void setNextFrame(byte[] data, Camera camera) {
    synchronized (mLock) {
        if (mPendingFrameData != null) {
            camera.addCallbackBuffer(mPendingFrameData.array());
            mPendingFrameData = null;
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this part of the code, we have two important pieces of information that are being managed: &lt;strong&gt;&lt;em&gt;the timestamp and the frame ID&lt;/em&gt;&lt;/strong&gt;. These values are crucial for understanding the timing of the frames received and determining if any frames were dropped during the process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     mPendingTimeMillis = SystemClock.elapsedRealtime() - mStartTimeMillis;
        mPendingFrameId++;
        mPendingFrameData = mBytesToByteBuffer.get(data);

        // Notify the processor thread if it is waiting on the next frame (see below).
        mLock.notifyAll();
    }
}
Press Ctrl+F12 to search for run:

public void run() {
            Frame outputFrame;
            ByteBuffer data;

            while (true) {
                synchronized (mLock) {
                    if (mActive &amp;amp;&amp;amp; (mPendingFrameData == null)) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException e) {
                            Log.d(TAG, "Frame processing loop terminated.", e);
                            return;
                        }
                    }

                    if (!mActive) {
                        return;
                    }

                    outputFrame = new Frame.Builder()
                            .setImageData(mPendingFrameData, mPreviewSize.getWidth(),
                                    mPreviewSize.getHeight(), ImageFormat.NV21)
                            .setId(mPendingFrameId)
                            .setTimestampMillis(mPendingTimeMillis)
                            .setRotation(mRotation)
                            .build();

                    data = mPendingFrameData;
                    mPendingFrameData = null;
                }

                try {
                    mDetector.receiveFrame(outputFrame);
                } catch (Throwable t) {
                    Log.e(TAG, "Exception thrown from receiver.", t);
                } finally {
                    mCamera.addCallbackBuffer(data.array());
                }
            }
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have the cached data, we use it to create an output frame. This frame is then passed to the "&lt;code&gt;receiveFrame&lt;/code&gt;" method, which is an asynchronous interface. &lt;/p&gt;

&lt;p&gt;To receive the results of the barcode detection, we need to associate the multi-processor instance, specifically the "&lt;code&gt;BarcodeCaptureActivity.java&lt;/code&gt;" class, with the barcode detector.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay);
barcodeDetector.setProcessor(new MultiProcessor.Builder&amp;lt;&amp;gt;(barcodeFactory).build());
Create a tracker (BarcodeTrackerFactory.java) for each barcode:

@Override
public Tracker&amp;lt;Barcode&amp;gt; create(Barcode barcode) {
    BarcodeGraphic graphic = new BarcodeGraphic(mGraphicOverlay);
    return new BarcodeGraphicTracker(mGraphicOverlay, graphic);
}
Update graphics (BarcodeGraphicTracker.java) as follows:

@Override
public void onUpdate(Detector.Detections&amp;lt;Barcode&amp;gt; detectionResults, Barcode item) {
    mOverlay.add(mGraphic);
    mGraphic.updateItem(item);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Android Barcode Reader with Third-Party SDK
&lt;/h2&gt;

&lt;p&gt;Google's demo provides us with a foundation to work with. We don't have to start building the barcode reader from scratch. Instead, we can use the demo as a starting point and make modifications, such as adding barcode format options. Additionally, we can replace the Google Vision API with the preview version of the &lt;a href="https://www.dynamsoft.com/barcode-reader/sdk-mobile/"&gt;Dynamsoft mobile barcode SDK&lt;/a&gt; for improved functionality.&lt;/p&gt;

&lt;p&gt;Next, you can make a LinearLayout and add four Switch widgets into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;LinearLayout
        android:layout\_width="match\_parent"
        android:layout\_height="match\_parent"
        android:layout\_above="@+id/auto\_focus"
        android:layout\_below="@+id/status\_message"
        android:layout\_centerVertical="true"
        android:orientation="vertical"
        &amp;gt;
        &amp;lt;Switch
            android:layout\_width="wrap\_content"
            android:layout\_height="wrap\_content"
            android:text="@string/dbr\_1d"
            android:id="@+id/dbr\_1d"
            android:switchPadding="50dp"
            android:checked="true"
            android:layout\_marginTop="180dp"/&amp;gt;
        &amp;lt;Switch
            android:layout\_width="wrap\_content"
            android:layout\_height="wrap\_content"
            android:text="@string/dbr\_qr"
            android:id="@+id/dbr\_qr"
            android:switchPadding="50dp"
            android:checked="true" /&amp;gt;
        &amp;lt;Switch
            android:layout\_width="wrap\_content"
            android:layout\_height="wrap\_content"
            android:text="@string/dbr\_data\_matrix"
            android:id="@+id/dbr\_data\_matrix"
            android:checked="true" /&amp;gt;
        &amp;lt;Switch
            android:layout\_width="wrap\_content"
            android:layout\_height="wrap\_content"
            android:text="@string/dbr\_pdf417"
            android:id="@+id/dbr\_pdf"
            android:switchPadding="20dp"
            android:checked="true" /&amp;gt;
    &amp;lt;/LinearLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create CameraListener (CameraSource.java) for asynchronously updating UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private CameraListener mCameraListener;
    public void setCameraListener(CameraListener listener) {
        mCameraListener = listener;
    }

    public interface CameraListener {
        public void onBarcodeResults(com.dynamsoft.barcode.ReadResult result);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;com.google.android.gms.vision.Detector&lt;/code&gt; with &lt;code&gt;com.dynamsoft.barcode.BarcodeReader&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void run() {
            ByteBuffer data;

            while (true) {
                synchronized (mLock) {
                    if (mActive &amp;amp;&amp;amp; (mPendingFrameData == null)) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException e) {
                            Log.d(TAG, "Frame processing loop terminated.", e);
                            return;
                        }
                    }

                    if (!mActive) {
                        return;
                    }

                    data = mPendingFrameData;
                    mPendingFrameData = null;
                }

                try {
                    byte\[\] buff = data.array();
                    com.dynamsoft.barcode.ReadResult dbrResult = mDetector.readSingle(buff, mPreviewSize.getWidth(), mPreviewSize.getHeight(), mBarcodeFormat);
                    if (mCameraListener != null) {
                        mCameraListener.onBarcodeResults(dbrResult);
                    }

                } catch (Throwable t) {
                    Log.e(TAG, "Exception thrown from receiver.", t);
                } finally {
                    mCamera.addCallbackBuffer(data.array());
                }
            }
        }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scan barcode images:&lt;br&gt;
Tap the screen to get the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private boolean onTap(float rawX, float rawY) {

        //TODO: use the tap position to select the barcode.
        BarcodeGraphic graphic = mGraphicOverlay.getFirstGraphic();
        com.dynamsoft.barcode.Barcode barcode = null;
        if (graphic != null) {
            barcode = graphic.getBarcode();
            if (barcode != null) {
                Intent data = new Intent();
                data.putExtra(BarcodeObject, barcode.displayValue);
                setResult(1, data);
                finish();
            }
            else {
                Log.d(TAG, "barcode data is null");
            }
        }
        else {
            Log.d(TAG,"no barcode detected");
        }
        return barcode != null;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're interested in trying out the preview version of the Dynamsoft mobile barcode reader SDK for Android and iOS, you can reach out to &lt;a href="mailto:support@dynamsoft.com"&gt;support@dynamsoft.com&lt;/a&gt; for more information. Alternatively, if you prefer open source options, you can replace the Google Vision APIs with ZXing and ZBar, which are popular open source mobile barcode SDKs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Code&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/yushulx/android-barcode-reader-demo"&gt;https://github.com/yushulx/android-barcode-reader-demo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>api</category>
    </item>
    <item>
      <title>The Fastest Way to Build an Android QR Code Scanner using Java</title>
      <dc:creator>Eric Parker 🥂</dc:creator>
      <pubDate>Wed, 28 Jun 2023 04:33:53 +0000</pubDate>
      <link>https://dev.to/iamparkereric/the-fastest-way-to-build-an-android-qr-code-scanner-using-java-3bo7</link>
      <guid>https://dev.to/iamparkereric/the-fastest-way-to-build-an-android-qr-code-scanner-using-java-3bo7</guid>
      <description>&lt;p&gt;QR codes are becoming increasingly popular because they facilitate fast data retrieval, smooth financial transactions, and exciting new possibilities for personalization. Using a QR code scanner helps quickly access URLs, product information, event details, and special offers. &lt;/p&gt;

&lt;p&gt;The two main features of any reliable QR code scanner app are the camera preview and the scanning of QR codes. While dozens of QR code scanner applications are available on the Google Play Store, making your own QR code scanner is a much better option. What if we told you it could be done with just a few easy steps? In this blog, we will be sharing the quickest way to build an Android QR code scanner. You will discover how to implement camera preview and &lt;a href="https://www.dynamsoft.com/barcode-reader/barcode-types/qr-code/"&gt;QR code scanning SDK&lt;/a&gt; in a step-by-step manner. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To implement the QR code scanner on Android, the following libraries are required. You are free to substitute your own libraries in their place.&lt;/p&gt;

&lt;p&gt;Camera Preview SDK&lt;br&gt;
CameraX&lt;/p&gt;

&lt;p&gt;Since the Android Camera2 API is exceptionally challenging for beginners, Google released CameraX to streamline the development of camera applications. The codelab tutorial is an excellent introduction to CameraX.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You'll have to add the camera permission in AndroidManifest.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;uses-feature android:name="android.hardware.camera.any" /&amp;gt;
  &amp;lt;uses-permission android:name="android.permission.CAMERA" /&amp;gt;
In app/build.gradle, add the dependency:
  dependencies {
      ...
      def camerax_version = "1.0.1"
      implementation "androidx.camera:camera-camera2:$camerax_version"
      implementation "androidx.camera:camera-lifecycle:$camerax_version"
      implementation "androidx.camera:camera-view:1.0.0-alpha27"
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dynamsoft Camera Enhancer v2.3&lt;/strong&gt;&lt;br&gt;
Dynamsoft Camera Enhancer, like CameraX, is a wrapper for the Android Camera2 API. It has all the functionality of a regular camera, plus frame filtering to improve the quality of your shots. &lt;/p&gt;

&lt;p&gt;To evaluate CameraX, we also employ Dynamsoft Camera Enhancer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br&gt;
Add the custom maven repository in settings.gradle, add the custom maven repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; dependencyResolutionManagement {
      repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
      repositories {
          ...
          maven{url "https://download2.dynamsoft.com/maven/dce/aar"}
      }
  }
Now, in app/build.gradle, add the dependency:
  dependencies {
      ...
      implementation 'com.dynamsoft:dynamsoftcameraenhancer:2.1.0@aar'
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  QR Code Scanning SDK
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.dynamsoft.com/barcode-reader/sdk-mobile/"&gt;Dynamsoft Barcode Reader v9.6&lt;/a&gt;&lt;br&gt;
A barcode SDK that supports all standard linear barcode and 2D barcode formats.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br&gt;
Add the custom maven repository in settings.gradle,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencyResolutionManagement {
      repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
      repositories {
          ...
          maven{url "https://download2.dynamsoft.com/maven/dbr/aar"}
      }
  }
In app/build.gradle, add the dependency:
dependencies {
      ...
      implementation 'com.dynamsoft:dynamsoftbarcodereader:9.0.0@aar'
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, a license key is required to activate the barcode SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; BarcodeReader.initLicense(
      "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==",
          new DBRLicenseVerificationListener() {
              @Override
              public void DBRLicenseVerificationCallback(boolean isSuccessful, Exception e) {
              }
          });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Develop Android Camera Preview within 5 Minutes!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Implement Camera Preview with CameraX in Three Simple Steps
&lt;/h3&gt;

&lt;p&gt;The default CameraX documentation is written in Kotlin. However, we will be using Java here. &lt;/p&gt;

&lt;p&gt;Build the user interface layout containing the CameraX preview view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
 &amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     tools:context=".CameraXActivity"&amp;gt;

     &amp;lt;androidx.camera.view.PreviewView
         android:id="@+id/camerax_viewFinder"
         android:layout_width="match_parent"
         android:layout_height="match_parent" /&amp;gt;

 &amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's check and request camera permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.dce_main);
     previewView = findViewById(R.id.dce_viewFinder);
     cameraEnhancer = new CameraEnhancer(this);
     cameraEnhancer.setCameraView(previewView);
     cameraEnhancer.addListener(this);
 }
 @Override
 protected void onResume() {
     super.onResume();
     try {
         cameraEnhancer.open();
     } catch (CameraEnhancerException e) {
         e.printStackTrace();
     }
 }
 @Override
 protected void onPause() {
     super.onPause();
     try {
         cameraEnhancer.close();
     } catch (CameraEnhancerException e) {
         e.printStackTrace();
     }
 }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  All in One
&lt;/h2&gt;

&lt;p&gt;We'll construct an entrance activity for launching CameraX and Dynamsoft Camera Enhancer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.example.qrcodescanner;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
public class EntryChoiceActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.entry_choice);
        findViewById(R.id.camerax_entry_point).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(EntryChoiceActivity.this, CameraXActivity.class);
                startActivity(intent);
            }
        });
        findViewById(R.id.dce_entry_point).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(EntryChoiceActivity.this, DceActivity.class);
                startActivity(intent);
            }
        });
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Turn Android Camera into QR Code Scanner
&lt;/h2&gt;

&lt;p&gt;To scan a QR code, we must continuously retrieve the camera's preview frames and send them to the QR code detector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting the Camera Frame Callback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ImageAnalysis class can be used to receive the camera frames when using CameraX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ImageAnalysis analysisUseCase = new ImageAnalysis.Builder().build();
analysisUseCase.setAnalyzer(cameraExecutor,
        imageProxy -&amp;gt; {
            // image processing
            // Must call close to keep receiving frames.
            imageProxy.close();
        });
cameraProvider.bindToLifecycle(this, cameraSelector, previewUseCase, analysisUseCase);
In comparison, Dynamsoft Camera Enhancer is significantly simpler. The callback function resembles that of Android Camera1:
public class DceActivity extends AppCompatActivity implements DCEFrameListener {
    @Override
    public void frameOutputCallback(DCEFrame dceFrame, long l) {
        // image processing
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different data types are returned by their response functions. For subsequent use, data type conversion is required.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Decode QR Codes?
&lt;/h2&gt;

&lt;p&gt;When using CameraX, ByteBuffer is firstly converted to byte[] and then the decodeBuffer() method is called:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;analysisUseCase.setAnalyzer(cameraExecutor,
imageProxy -&amp;gt; {
    TextResult[] results = null;
    ByteBuffer buffer = imageProxy.getPlanes()[0].getBuffer();
    int nRowStride = imageProxy.getPlanes()[0].getRowStride();
    int nPixelStride = imageProxy.getPlanes()[0].getPixelStride();
    int length = buffer.remaining();
    byte[] bytes = new byte[length];
    buffer.get(bytes);
    try {
        results = reader.decodeBuffer(bytes, imageProxy.getWidth(), imageProxy.getHeight(), nRowStride * nPixelStride, EnumImagePixelFormat.IPF_NV21, "");
    } catch (BarcodeReaderException e) {
        e.printStackTrace();
    }
    // Must call close to keep receiving frames.
    imageProxy.close();
});

When using Dynamsoft Camera Enhancer, we get Bitmap from the DCEFrame and then the decodeBufferedImage() method is called: 

public void frameOutputCallback(DCEFrame dceFrame, long l) {
    TextResult[] results = null;
    try {
        results = reader.decodeBufferedImage(dceFrame.toBitmap(), "");
    } catch (BarcodeReaderException e) {
        e.printStackTrace();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Use Zoom and Torch to Enhance the Frame Quality
&lt;/h2&gt;

&lt;p&gt;The accuracy of barcode recognition is always dependent on the quality of the input image. The image can be enlarged by zooming the camera if the QR code is very small. If the input image is too poorly lit, we can activate the flashlight to enhance it. Both CameraX and Dynasoft Camera Enhancer have supported the camera control in full.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Android Camera Zoom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using the finger pinch gesture, the zoom can be triggered. Hence, firstly we'll build the gesture detector and take over the onTouchEvent() method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ZoomController {
    public final static String TAG = "ZoomController";
    private float currentFactor = 1.0f;
    private float minZoomRatio = 1.0f, maxZoomRatio = 1.0f;
    private ZoomStatus zoomStatus;
    private ScaleGestureDetector scaleGestureDetector;
    private ScaleGestureDetector.OnScaleGestureListener scaleGestureListener = new ScaleGestureDetector.OnScaleGestureListener() {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            Log.i(TAG, "onScale: " + detector.getScaleFactor());
            currentFactor = detector.getScaleFactor() * currentFactor;
            if (currentFactor &amp;lt; minZoomRatio) currentFactor = minZoomRatio;
            if (currentFactor &amp;gt; maxZoomRatio) currentFactor = maxZoomRatio;
            if (zoomStatus != null) {
                zoomStatus.onZoomChange(currentFactor);
            }
            return true;
        }
        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            return true;
        }
        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
        }
    };
    public ZoomController(Activity activity) {
        scaleGestureDetector = new ScaleGestureDetector(activity, scaleGestureListener);
    }
    public interface ZoomStatus {
        void onZoomChange(float ratio);
    }
    public void addListener(ZoomStatus zoomStatus) {
        this.zoomStatus = zoomStatus;
    }
    public void initZoomRatio(float minZoomRatio, float maxZoomRatio) {
        this.minZoomRatio = minZoomRatio;
        this.maxZoomRatio = maxZoomRatio;
    }
    public boolean onTouchEvent(MotionEvent event) {
        return scaleGestureDetector.onTouchEvent(event);
    }
}
@Override
public boolean onTouchEvent(MotionEvent event) {
    zoomController.onTouchEvent(event);
    return super.onTouchEvent(event);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the gesture is detected, we'll get the scale factor and use that as the zoom ratio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting camera zoom ratio with CameraX&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (camera != null) {
    camera.getCameraControl().setZoomRatio(ratio);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Setting camera zoom ratio with Dynamsoft Camera Enhancer&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try {
    cameraEnhancer.setZoom(ratio);
} catch (CameraEnhancerException e) {
    e.printStackTrace();
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Android Camera Torch&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To instantly turn on the flashlight, we keep an eye on the light value the light sensor gives us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class AutoTorchController implements SensorEventListener {
    public final static String TAG = "AutoTorchController";
    private SensorManager sensorManager;
    private TorchStatus torchStatus;
    public interface TorchStatus {
        void onTorchChange(boolean status);
    }
    public AutoTorchController(Activity activity) {
        sensorManager = (SensorManager)activity.getSystemService(SENSOR_SERVICE);
    }
    public void onStart() {
        Sensor lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
        if(lightSensor != null){
            sensorManager.registerListener(
                    this,
                    lightSensor,
                    SensorManager.SENSOR_DELAY_NORMAL);
        }
    }
    public void onStop() {
        sensorManager.unregisterListener(this);
    }
    @Override
    public void onSensorChanged(SensorEvent event) {
        if(event.sensor.getType() == Sensor.TYPE_LIGHT){
            if (event.values[0] &amp;lt; 20) {
                if (torchStatus != null) torchStatus.onTorchChange(true);
            }
            else {
                if (torchStatus != null) torchStatus.onTorchChange(false);
            }
        }
    }
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
    public void addListener(TorchStatus torchStatus) {
        this.torchStatus = torchStatus;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Toggling camera torch with CameraX&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (camera != null) camera.getCameraControl().enableTorch(status);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Toggling camera torch with Dynamsoft Camera Enhancer&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (status) {
    try {
        cameraEnhancer.turnOnTorch();
    } catch (CameraEnhancerException e) {
        e.printStackTrace();
    }
}
else {
    try {
        cameraEnhancer.turnOffTorch();
    } catch (CameraEnhancerException e) {
        e.printStackTrace();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>android</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Integrate Barcode Reading Functionality into .NET Applications</title>
      <dc:creator>Eric Parker 🥂</dc:creator>
      <pubDate>Mon, 10 Apr 2023 10:07:40 +0000</pubDate>
      <link>https://dev.to/iamparkereric/how-to-integrate-barcode-reading-functionality-into-net-applications-498a</link>
      <guid>https://dev.to/iamparkereric/how-to-integrate-barcode-reading-functionality-into-net-applications-498a</guid>
      <description>&lt;p&gt;To integrate barcode reading functionality into .NET applications, you can use a barcode reader SDK. Here we'll use Dynamsoft Barcode Reader SDK for .NET because it provides an easy and efficient way to add barcode reading functionality. It can save developers a significant amount of time and effort compared to building barcode recognition from scratch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some specific advantages of using a barcode reader SDK include:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;- Speed and accuracy:&lt;/strong&gt; It uses advanced algorithms and techniques to read barcodes quickly and reliably, even in challenging conditions such as low light or blurry images.&lt;br&gt;
&lt;strong&gt;- Cross-platform support:&lt;/strong&gt; It can work with multiple platforms and programming languages, allowing developers to add barcode reading functionality to their applications on a wide range of devices and operating systems.&lt;br&gt;
&lt;strong&gt;- Customization and flexibility:&lt;/strong&gt; It provide a range of configuration options and settings, allowing developers to customize the barcode reading process.&lt;/p&gt;

&lt;p&gt;So, Let's start with implementation of barcode reading functionality using the Dynamsoft &lt;a href="https://www.dynamsoft.com/barcode-reader/docs/server/programming/dotnet/user-guide.html"&gt;Barcode Reader SDK for .NET&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download and install the Dynamsoft Barcode Reader SDK for .NET from the Dynamsoft website.&lt;/li&gt;
&lt;li&gt;Create a new .NET project in Visual Studio. &lt;/li&gt;
&lt;li&gt;Add a reference to the Dynamsoft Barcode Reader DLL in your project. To do this, right-click on your project in the Solution Explorer and select "Add Reference." Browse to the DLL file for the SDK and add it as a reference. &lt;/li&gt;
&lt;li&gt;In your code, add the following using statements:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Dynamsoft.Barcode;
using System.Drawing;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Instantiate a BarcodeReader object:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BarcodeReader reader = new BarcodeReader();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Configure the barcode reader. For example, to recognize only QR codes, you can set the BarcodeFormat property:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;reader.BarcodeFormat = BarcodeFormat.QR_CODE;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Load the image containing the barcode. For example, if you have an image file named "barcode.png" in your project directory, you can load it like this:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bitmap barcodeImage = new Bitmap("barcode.png");

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Call the DecodeBitmap method of the BarcodeReader object, passing the barcode image as a parameter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BarcodeResult[] results = reader.DecodeBitmap(barcodeImage);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Loop through the results array to extract information about the barcodes that were recognized:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foreach (BarcodeResult result in results)
{
    Console.WriteLine("Barcode Type: " + result.BarcodeFormat);
    Console.WriteLine("Barcode Value: " + result.BarcodeText);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple example to get you started. The Dynamsoft Barcode Reader SDK for .NET provides many more options and features for barcode recognition, such as support for multiple barcode formats, batch scanning, and more. &lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://www.dynamsoft.com/barcode-reader/docs/server/programming/dotnet/"&gt;https://www.dynamsoft.com/barcode-reader/docs/server/programming/dotnet/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>dotnet</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Create a Web App to Read Multiple Barcodes Using Dynamsoft</title>
      <dc:creator>Eric Parker 🥂</dc:creator>
      <pubDate>Fri, 17 Mar 2023 07:12:22 +0000</pubDate>
      <link>https://dev.to/iamparkereric/create-a-web-app-to-read-multiple-barcodes-using-dynamsoft-2npb</link>
      <guid>https://dev.to/iamparkereric/create-a-web-app-to-read-multiple-barcodes-using-dynamsoft-2npb</guid>
      <description>&lt;h2&gt;
  
  
  What is Multiple Barcode Scanning?
&lt;/h2&gt;

&lt;p&gt;Multiple barcode scanning is the process of scanning and decoding multiple barcodes in a single image or frame. &lt;/p&gt;

&lt;p&gt;Users can capture multiple barcodes in a single shot, which can be helpful in situations where there are several products or items that need to be scanned quickly. For example, in a retail store, a cashier can scan multiple barcodes on a single carton of products instead of scanning each product one by one.&lt;/p&gt;

&lt;p&gt;Here is a high-level overview of how to create a web app to read multiple barcodes using Dynamsoft.  By following the steps explained below, you should be able to create a functional app that can &lt;a href="https://www.dynamsoft.com/blog/insights/scan-multiple-barcodes-and-qr-codes-at-once/"&gt;scan multiple barcodes&lt;/a&gt; from a single image.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new vanilla TypeScript project using Vite.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vite@latest example -- --template vanilla-ts

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install &lt;a href="https://www.dynamsoft.com/barcode-reader/overview/"&gt;Dynamsoft Barcode Reader&lt;/a&gt; as a dependency.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install dynamsoft-javascript-barcode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the index.html, add an input element for selecting a file, a button to read barcodes and an SVG element to show the results.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;link rel="icon" type="image/svg+xml" href="/vite.svg" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;Vite + TS&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id="app"&amp;gt;
      &amp;lt;div class="barcode-reader"&amp;gt;
        &amp;lt;div&amp;gt;
          Load local image:
          &amp;lt;input type="file" id="barcodeFile" accept=".jpg,.jpeg,.png,.bmp" /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;
          &amp;lt;button id="decodeButton"&amp;gt;Decode&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div id="status"&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;svg id="resultSVG" version="1.1" xmlns="http://www.w3.org/2000/svg"&amp;gt;&amp;lt;/svg&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script type="module" src="/src/main.ts"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Load the selected image file and display it in the SVG element.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let img;
window.onload = function(){
  let barcodeFile = document.getElementById('barcodeFile') as HTMLInputElement;
  barcodeFile.addEventListener("change",function(){
    loadImageFromFile();
  })
}

function loadImageFromFile() { 
  console.log("loadImageFromFile");
  let barcodeFile = document.getElementById('barcodeFile') as HTMLInputElement;
  let files = barcodeFile.files as FileList;
  if (files.length == 0) {
    return;
  }
  let file = files[0];
  let fileReader = new FileReader();
  fileReader.onload = function(e:any){
    loadImage(e.target.result);
  };
  fileReader.onerror = function () {
    console.warn('oops, something went wrong.');
  };
  fileReader.readAsDataURL(file);
}

function loadImage(imgsrc:string){
  if (imgsrc) {
    img = new Image();
    img.src = imgsrc;
    img.onload = function(){
      let svgElement = document.getElementById("resultSVG") as HTMLElement;
      svgElement.innerHTML = "";
      let svgImage = document.createElementNS("http://www.w3.org/2000/svg", "image");
      svgImage.setAttribute("href",imgsrc);
      svgElement.setAttribute("viewBox","0 0 "+img.width+" "+img.height);
      svgElement.appendChild(svgImage);
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Read barcodes from the selected image and overlay the results in the SVG element when the decode button is clicked. Initialize Dynamsoft Barcode Reader if it has not been initialized. You may need to apply for a license to use it.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let reader:BarcodeReader;
let results:TextResult[];
window.onload = function(){
  let decodeButton = document.getElementById('decodeButton') as HTMLButtonElement;
  decodeButton.addEventListener("click",function(){
    decodeImg();
  })
}

async function decodeImg(){
  if (!img) {
    return;
  }
  let status = document.getElementById("status") as HTMLElement;
  if (!reader) {
    await initDBR();
  }
  status.innerText = "decoding...";
  results = await reader.decode(img);
  console.log(results);
  overlayResults(results);
  status.innerText = "";
}

async function initDBR(){
  let status = document.getElementById("status") as HTMLElement;
  status.innerText = "initializing...";
  BarcodeReader.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@9.6.10/dist/";
  BarcodeReader.license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="; //one-day public trial
  reader = await BarcodeReader.createInstance();
  status.innerText = "";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Overall, creating a web app to read multiple barcodes requires knowledge of HTML, CSS, JavaScript, and the Dynamsoft barcode scanning API.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Build a Web Page to Scan Documents Online with Minimal JavaScript Coding</title>
      <dc:creator>Eric Parker 🥂</dc:creator>
      <pubDate>Tue, 06 Dec 2022 06:46:33 +0000</pubDate>
      <link>https://dev.to/iamparkereric/build-a-web-page-to-scan-documents-online-with-minimal-javascript-coding-3d0h</link>
      <guid>https://dev.to/iamparkereric/build-a-web-page-to-scan-documents-online-with-minimal-javascript-coding-3d0h</guid>
      <description>&lt;p&gt;Want to build a web page to scan documents online? Well, you have arrived at the right spot! This blog will introduce you to a technology that will help cut extensive development time and effort. So, without further ado, let's get started. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to Quickly Build a Web Page to Scan Documents Online?
&lt;/h2&gt;

&lt;p&gt;To build a web page on your own to scan documents in a web browser, you'll either have to develop a module from scratch or choose a document scanning SDK. The latter is a better option as it eliminates the need to perform complex coding and saves time and effort. &lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing the Right Document Scanner SDK
&lt;/h3&gt;

&lt;p&gt;Document scanners cannot be directly accessed by a web page like a web camera. Hence, it requires a bridge to communicate with scanners. The TWAIN scanning protocol is the most preferred and recommended when working with document scanners. &lt;/p&gt;

&lt;p&gt;Choosing the correct document scanner SDK may be challenging for you, with so many available options. The below parameters will help make your selection easier. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy Integration:&lt;/strong&gt; The document scanner SDK you choose must be easy to integrate. Building a document scanning module for your website should not take more than a few lines of JavaScript code. Hence, you must choose the one that is easy to integrate. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Supported OS, Browsers, and Technology:&lt;/strong&gt; Are you using a Windows system or a MacBook? Which browser are you using? Is it Safari, Chrome, or Firefox? Select a document scanner SDK that supports a wide range of OS and browsers. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fast Speed:&lt;/strong&gt; Speed is another crucial aspect you may want to consider while looking for a document scanner SDK for the web. The top ones can scan thousands of documents in a single session. Choosing such options will save you time and effort.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sharing and Downloading Options:&lt;/strong&gt; For easy sharing and downloading, ensure the document scanner SDK that you choose supports formats such as JPEG, BMP, PNG, PDF, and TIFF files. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Basic Editing Features:&lt;/strong&gt; You wouldn't want to use a separate document editor to make fundamental changes such as crop, mirror, flip, erase, rotate, etc. Hence, look for a &lt;a href="https://www.dynamsoft.com/web-twain/overview/" rel="noopener noreferrer"&gt;document scanner SDK&lt;/a&gt; with built-in basic image editing interfaces. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Robust Security Features:&lt;/strong&gt; Even if you use the document scanner SDK for personal use, you cannot compromise the security part. Hence, look for standard security features such as data encryption, built-in HTTPS support, digital signature, authorization access for accessing local files, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Considering these features, you can easily choose the perfect document scanner SDK for your requirements. Also, try online demos and perform detailed analyses to make an informed decision. You may also compare multiple options and finalize the best per your needs. &lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Web Page with a Document Scanner SDK
&lt;/h2&gt;

&lt;p&gt;Let's learn how to build a web page with a document scanning SDK to &lt;a href="https://www.dynamsoft.com/blog/insights/scan-documents-images-and-upload-online/" rel="noopener noreferrer"&gt;scan documents online&lt;/a&gt;. Here, we have used Dynamsoft's Dynamic Web TWAIN SDK. It is very easy to use and implement. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; To configure the license key, open /Resources/dynamsoft.webtwain.config.js &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dynamsoft.DWT.ProductKey = 'LICENSE KEY';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Now, you'll need to copy /Resources to the static resource folder of your web project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; In this step, you'll have to make an index.html file. The code snippet explains how to scan documents from cameras or scanners.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
 &amp;lt;html&amp;gt;

 &amp;lt;head&amp;gt;
     &amp;lt;title&amp;gt;Scan Document from Scanner&amp;lt;/title&amp;gt;
     &amp;lt;script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js"&amp;gt;&amp;lt;/script&amp;gt;
     &amp;lt;script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js"&amp;gt;&amp;lt;/script&amp;gt;
 &amp;lt;/head&amp;gt;

 &amp;lt;body&amp;gt;
     &amp;lt;input type="button" value="scan" onclick="acquireScanner();" /&amp;gt;

     &amp;lt;div id="container"&amp;gt;&amp;lt;/div&amp;gt;

     &amp;lt;script type="text/javascript"&amp;gt;
         var scannerObj;
         Dynamsoft.DWT.CreateDWTObjectEx({
             WebTwainId: 'scanner',
             UseLocalService: true,
         }, function (obj) {
             scannerObj = obj;
             scannerObj.Viewer.bind(document.getElementById('container'));
             scannerObj.Viewer.width = 480;
             scannerObj.Viewer.height = 640;
             scannerObj.Viewer.show();
         }, function (ec, es) {
             console.log(es);
         });

         function acquireScanner() {
             if (scannerObj) {
                 var OnacquireScannerSuccess, OnacquireScannerFailure;
                 OnacquireScannerSuccess = OnacquireScannerFailure = function () {
                     scannerObj.CloseSource();
                 };

                 scannerObj.SelectSource();
                 scannerObj.OpenSource();
                 scannerObj.IfDisableSourceAfterAcquire = true;
                 scannerObj.AcquireImage(OnacquireScannerSuccess, OnacquireScannerFailure);
             }
         }
     &amp;lt;/script&amp;gt;
 &amp;lt;/body&amp;gt;
 &amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's build an index2.html file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
 &amp;lt;html&amp;gt;

 &amp;lt;head&amp;gt;
     &amp;lt;title&amp;gt;Use Dynamic Web TWAIN to Scan from Camera&amp;lt;/title&amp;gt;
     &amp;lt;script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js"&amp;gt;&amp;lt;/script&amp;gt;
     &amp;lt;script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js"&amp;gt;&amp;lt;/script&amp;gt;
     &amp;lt;script type="text/javascript" src="Resources/addon/dynamsoft.webtwain.addon.camera.js"&amp;gt;&amp;lt;/script&amp;gt;
 &amp;lt;/head&amp;gt;

 &amp;lt;body&amp;gt;
     &amp;lt;div id="container" style="width: 720px;height:720px"&amp;gt;&amp;lt;/div&amp;gt;

     &amp;lt;script type="text/javascript"&amp;gt;
         var cameraObj;
         Dynamsoft.DWT.CreateDWTObjectEx({
             WebTwainId: 'camera',
             UseLocalService: false
         }, function (obj) {
             cameraObj = obj;
             cameraObj.Viewer.bind(document.createElement('div'));
             cameraObj.Addon.Camera.scanDocument({
                 element: document.getElementById("container"),
                 scannerViewer: {
                     fullScreen: true
                 }
             }).then(
                 function () { console.log("OK"); },
                 function (error) { console.log(error.message); });

         }, function (ec, es) {
             console.log(es);
         });

     &amp;lt;/script&amp;gt;
 &amp;lt;/body&amp;gt;

 &amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To control the API behavior, the boolean parameter UseLocalService is utilized. Setting it to 'true' would allow the SDK to communicate with the local Dynamsoft service to acquire images from scanners. When it is set to 'false,' the SDK would directly call JavaScript APIs to capture camera images.&lt;/p&gt;

&lt;p&gt;Using the Document Scanning Widget &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;scanDocument()&lt;/code&gt; API builds a full-functional widget that supports triggering document edge detection, setting camera resolution, images from local storage, loading switching between the rear and front cameras, managing multiple documents, and auto-capturing documents. &lt;/p&gt;

&lt;p&gt;Entering the document management viewer will allow you to save and edit documents. To all auto-captured documents, perspective correction is applied in the viewer. You can also use filters if the document quality is not that great. &lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
  </channel>
</rss>
