How to Scan Barcodes in Jupyter Notebook Using Python and OpenCV
Jupyter Notebook is a web-based interactive computing environment that lets you combine live code, equations, visualizations, and narrative text in a single document. If you have Anaconda installed, Jupyter Notebook is included by default. This tutorial walks you through building a Python barcode scanner inside a Jupyter Notebook — upload an image, decode every barcode in it, and display the annotated results inline.
What you’ll build: An interactive Jupyter Notebook that accepts image uploads via a widget button, scans all barcodes and QR codes using Dynamsoft Barcode Reader and OpenCV, and renders annotated results side-by-side with Matplotlib.
Key Takeaways
- Dynamsoft Barcode Reader’s Python SDK can decode 1D/2D barcodes from image files inside a Jupyter Notebook in a single API call via
CaptureVisionRouter. - The
ipywidgets.FileUploadwidget provides a zero-JavaScript way to accept image uploads directly in a notebook cell. - OpenCV handles image decoding and barcode-location overlay drawing, while Matplotlib renders the before/after comparison inline.
- This approach works in both classic Jupyter Notebook and JupyterLab with no extra frontend extensions required.
Common Developer Questions
How do I scan barcodes from an uploaded image in Jupyter Notebook using Python?
Use an ipywidgets.FileUpload control to accept the image, decode the uploaded bytes with OpenCV, and then send the image into CaptureVisionRouter for barcode recognition. The notebook flow in this article keeps everything inline, so upload, decode, and result display all happen inside notebook cells.
What Python library can decode QR codes and 1D barcodes inside a Jupyter Notebook cell?
Dynamsoft Barcode Reader’s Python SDK is the library used here for both QR codes and 1D barcodes. It runs inside a notebook cell through CaptureVisionRouter, so you can decode uploaded images without building a separate desktop or web app first.
How do I display barcode detection results with bounding boxes in Jupyter Notebook?
Draw the barcode quadrilateral points onto a copy of the image with OpenCV, then render the original and annotated versions side-by-side with Matplotlib. That gives you an inline before-and-after view directly in Jupyter Notebook or JupyterLab.
Prerequisites
- Get a 30-day free trial license for Dynamsoft Barcode Reader.
Build a Barcode Scanner in Jupyter Notebook
-
Run Jupyter notebook:

-
Open
http://localhost:8888/in your browser to create abarcode_scanning.ipynbfile.
-
Insert a new cell to install Dynamsoft Barcode Reader, OpenCV, and Matplotlib:
%pip install dynamsoft-barcode-reader-bundle opencv-python matplotlib -
Initialize the license of barcode SDK and barcode reader object:
from dynamsoft_capture_vision_bundle import * license_key = "LICENSE-KEY" error_code, error_message = LicenseManager.init_license(license_key) cvr_instance = CaptureVisionRouter() -
Create an image upload button in Jupyter notebook:
from ipywidgets import FileUpload def on_upload_change(change): if change.name != "value": return if not change.new: return up = change.owner files_obj = change.new records = list(_flatten_records(files_obj)) for rec in records: try: content = _get_bytes(rec) except Exception as e: print("Skip unsupported record:", e) continue buf = np.frombuffer(content, dtype=np.uint8) img = cv.imdecode(buf, cv.IMREAD_COLOR) if img is None: print("Failed to decode image.") continue new_img = img.copy() try: decode(new_img) except Exception as e: print("Decode error:", e) img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB) new_rgb = cv.cvtColor(new_img, cv.COLOR_BGR2RGB) show_image(img_rgb, new_rgb) try: up.unobserve(on_upload_change, names="value") except Exception: pass reset_done = False for val in ((), [], None): try: up.value = val reset_done = True break except Exception: continue if not reset_done: try: up.value.clear() reset_done = True except Exception: pass try: up.observe(on_upload_change, names="value") except Exception: pass uploader = FileUpload(accept='image/*', multiple=True) uploader.observe(on_upload_change, names="value") uploader -
Convert the image data to numpy array and then decode the image with OpenCV API:
import cv2 as cv import numpy as np for rec in records: try: content = _get_bytes(rec) except Exception as e: print("Skip unsupported record:", e) continue buf = np.frombuffer(content, dtype=np.uint8) img = cv.imdecode(buf, cv.IMREAD_COLOR) -
Scan barcodes with Dynamsoft Barcode Reader API:
def decode(frame): before = time.time() result = cvr_instance.capture(frame, EnumPresetTemplate.PT_READ_BARCODES.value) after = time.time() COLOR_RED = (0, 0, 255) thickness = 2 text_x, text_y = 10, 20 if result.get_error_code() != EnumErrorCode.EC_OK: print("Error:", result.get_error_code(), result.get_error_string()) cv.putText(frame, f'{after - before:.2f} s, barcode found: 0', (text_x, text_y), cv.FONT_HERSHEY_SIMPLEX, 0.5, COLOR_RED) return items = result.get_items() found = len(items) for item in items: format_type = item.get_format() text = item.get_text() print(f'Format: {format_type}, Text: {text}') loc = item.get_location() pts = np.array([[p.x, p.y] for p in loc.points], dtype=np.int32) cv.drawContours(image=frame, contours=[pts], contourIdx=-1, color=COLOR_RED, thickness=thickness, lineType=cv.LINE_AA) cv.putText(frame, f'{format_type}', (pts[0][0], pts[0][1] - 10), cv.FONT_HERSHEY_SIMPLEX, 0.5, COLOR_RED) cv.putText(frame, f'{text}', (pts[0][0], pts[0][1] - 30), cv.FONT_HERSHEY_SIMPLEX, 0.5, COLOR_RED) cv.putText(frame, f'{after - before:.2f} s, barcode found: {found}', (text_x, text_y), cv.FONT_HERSHEY_SIMPLEX, 0.5, COLOR_RED) new_img = img.copy() decode(new_img) -
Display the barcode recognition results with Matplotlib:
import matplotlib.pyplot as plt def show_image(img1, img2): fig = plt.figure(figsize=(18, 8)) ax1 = fig.add_subplot(1, 2, 1) ax1.set_title('Input image', fontsize=14) ax1.axis('off') ax2 = fig.add_subplot(1, 2, 2) ax2.set_title('Barcode Recognition', fontsize=14) ax2.axis('off') ax1.imshow(img1) ax2.imshow(img2) plt.show()
Common Issues and Edge Cases
- “License has expired” or “License invalid” error: Ensure you have replaced
"LICENSE-KEY"with a valid trial or purchased license key. Trial keys expire after 30 days — request a new one from the Dynamsoft License Portal. FileUploadwidget does not appear: Theipywidgetspackage must be installed and the Jupyter Notebook extension enabled. Run%pip install ipywidgetsand restart the kernel. In JupyterLab, you may also needjupyter labextension install @jupyter-widgets/jupyterlab-manager.cv.imdecodereturnsNone: This typically means the uploaded file is not a valid image or is corrupted. Verify the file format (JPEG, PNG, BMP are supported) and ensure the file is not zero-length.