How to Read QR Codes from a Webcam in Delphi|Complete Guide Using ZXing.Delphi + DSPack
You can read QR codes and barcodes from a webcam in Delphi by combining
ZXing.Delphi with DSPack.
This page provides a detailed walkthrough of the entire process, including VCL form design,
library installation, event configuration, and the actual scanning logic, complete with sample code.
It is ideal for those who want to scan codes not from image files, but from
real‑time webcam video.
If you are looking for a QR Code Reader
If you need a free QR code reader for Windows,
please download and use
Mam WebCam QR Code Reader.
If you want to scan QR codes directly in your browser,
you can use
How to Create a Free JavaScript QR Code Reader (Webcam Supported).
Before You Begin
Using ZXing.Delphi (https://github.com/Spelt/ZXing.Delphi), you can scan images and convert
QR codes, Code39 barcodes, and other formats into text.
With DSPack, you can capture images from a webcam.
For instructions on installing DSPack into the Delphi IDE, please refer to:
https://mam-mam.net/en/delphi/dspack_install.html
By combining these two libraries, you can create a Windows application that reads QR codes
directly from a camera — essentially a full QR code scanner software built in Delphi.
Downloading ZXing.Delphi
Download the ZIP file from:
https://github.com/Spelt/ZXing.Delphi
Click “Code” → “Download ZIP” to download ZXing.Delphi-v_3.0.zip.
After downloading, extract the ZIP file.
Preparing to Create a QR Code Reader in Delphi
After launching the Delphi IDE, go to File → New → Windows VCL Application – Delphi
to create a new project.
Click Save All, then in:
..\Documents\Embarcadero\Studio\Projects
create a new folder (for example, Vcl_ZXing_DSPack) using the
New Folder button.
Save the unit as Unit1.pas inside this folder, and save the project as
Project1.dproj.
Next, extract the contents of ZXing.Delphi-v_3.0.zip, and copy the entire
Lib folder into your project folder:
..\Documents\Embarcadero\Studio\Projects\Vcl_ZXing_DSPack
Project Settings
Open Project → Options.
- Select Build → Delphi Compiler from the left pane.
- Set the target to All Configurations.
-
Enter the following under Conditional defines:
FRAMEWORK_VCL
(If you forget to add this and encounter a compile error, addFRAMEWORK_VCLhere and then run Project → Build All Projects.) -
Add the following paths to Search path:
Lib\Classes;Lib\Classes\Common;Lib\Classes\Common\Detector;Lib\Classes\Common\ReedSolomon; Lib\Classes\Filtering;Lib\Classes\1D Barcodes;Lib\Classes\2D Barcodes; Lib\Classes\2D Barcodes\Decoder;Lib\Classes\2D Barcodes\Detector - After adding the paths, click Save.
Required Components for the VCL Form
Drag and drop the following components onto the form:
- TVideoWindow
- TFilterGraph
- TFilter
- TSampleGrabber
- TTimer
- TMemo
Example Implementation of QR Code Scanning (ZXing + DSPack)
Copy and paste the following source code.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
DSPack, DXSUtil, DirectShow9,
ZXing.ReadResult, ZXing.BarCodeFormat, ZXing.ScanManager;
type
TForm1 = class(TForm)
VideoWindow1: TVideoWindow;
FilterGraph1: TFilterGraph;
Filter1: TFilter;
SampleGrabber1: TSampleGrabber;
Memo1: TMemo;
Timer1: TTimer;
procedure FilterGraph1GraphVideoSizeChanged(sender: TObject; Width,
height: Word);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FilterGraph1GraphVideoSizeChanged(sender: TObject; Width,
height: Word);
begin
VideoWindow1.Width:=320;
VideoWindow1.Height:=320*Height div Width;
end;
procedure TForm1.FormCreate(Sender: TObject);
var ICapB:ICaptureGraphBuilder2;
VideoDevices:TSysDevEnum; //Enumerate available video capture devices
begin
Timer1.Enabled:=False;
VideoDevices:=TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
try
Filter1.FilterGraph:=FilterGraph1;
Filter1.BaseFilter.Moniker:=VideoDevices.GetMoniker(0);
VideoWindow1.FilterGraph:=FilterGraph1;
SampleGrabber1.FilterGraph:=FilterGraph1;
FilterGraph1.ClearGraph;
FilterGraph1.Mode:=gmCapture;
FilterGraph1.Active:=True;
ICapB:=FilterGraph1 as ICaptureGraphBuilder2;
ICapB.RenderStream(@PIN_CATEGORY_PREVIEW,nil,Filter1 as IBaseFilter,
SampleGrabber1 as IBaseFilter,VideoWindow1 as IBaseFilter);
FilterGraph1.Play;
Timer1.Enabled:=True;
finally
VideoDevices.Free;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FilterGraph1.Stop;
FilterGraph1.Active:=False;
FilterGraph1.ClearGraph;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var bmp:TBitmap;
ScanManager:TScanManager;
ReadResult: TReadResult;
begin
bmp:=TBitmap.Create;
try
SampleGrabber1.GetBitmap(bmp);
ScanManager:=TScanManager.Create(TBarcodeFormat.Auto,nil);
try
ReadResult:=ScanManager.Scan(bmp);
if ReadResult<>nil then
Memo1.LInes.Add(ReadResult.text);
finally
ScanManager.Free;
end;
finally
bmp.Free
end;
end;
end.
Assign the procedures to the corresponding event properties.
| Event Property | Procedure |
|---|---|
| Form1.OnCreate | FormCreate |
| Form1.OnDestroy | FormDestroy |
| FilterGraph1.OnGraphVideoSizeChanged | FilterGraph1GraphVideoSizeChanged |
| Timer1.OnTimer | Timer1Timer |
Run the Application
Compile and run the application.
When you hold a QR code or a Code39 barcode in front of the camera, it will be scanned and the result will be output to Memo1.
