- Žarko Gajić
- On Delphi Programming
- FireMonkey / Mobile (Android, iOS) QR Code Generation Using Delphi XE 5 / DelphiZXingQRCode
- DelphiZXingQRCode -> FireMonkey Support
- Single Pixel Drawing (and Other Canvas Drawing) FireMonkey Style
- VCL’s Canvas.StretchDraw to FMX’s Canvas.DrawBitmap
- Delphi android qr code
- About
- ScannerMApp: a QR/barcode scanner app with Delphi, ZXing and TFrameStand
- Video demo
- Introduction
- Scanning barcodes
- The app structure
- Technologies
- What’s next and conclusion
Žarko Gajić
On Delphi Programming
FireMonkey / Mobile (Android, iOS) QR Code Generation Using Delphi XE 5 / DelphiZXingQRCode
The DelphiZXingQRCode unit, ported from ZXing by Debenu, allows to easily add QR Code generation to your Delphi VCL applications.
While the DelphiZXingQRCode was designed to support VCL applications (and be used in newer as well as in older Delphi versions), it can also easily be “upgraded” for Fire Monkey applications – be it desktop or mobile (Android, iOS).
DelphiZXingQRCode -> FireMonkey Support
To FireMonkey-enable the DelphiZXingQRCode unit a few changes to the source code were required.
The unit uses “contnrs” (System.Contnrs.pas) unit which implements TObjectList (used by the unit) and other container like classes. Under FireMonkey for mobile, more specifically under ARC, the classes contained in System.Contnrs.pas cannot be used because they are not ARC compliant.
Equivalent classes are to be found in System.Generics.Collections.pas (ARC compliant) where generics versions of TObjectList is defined.
Therefore, the first change is to replace “uses contnrs, …” with “uses System.Generics.Collections, …”
This also requires to make changes like: from “Blocks: TObjectList;” to “Blocks: TObjectList ;” – that is to use strongly typed generics list classes.
Further, there are lots of “ansistring” and “widestring” types used for parameters in various functions inside the unit. If you want to go mobile, those are not supported and you should use “string”. More info here: Migrating Delphi Code to Mobile from Desktop.
Therefore, the second change to the unit would be to replace “widestring” with “string” and “ansistring” with “array of byte” (or something else as explained in the article).
Single Pixel Drawing (and Other Canvas Drawing) FireMonkey Style
In the VCL, the TCanvas class allows accessing single pixels through the “Canvas.Pixels()” property. In FireMonkey this is not supported and you have to use the SetPixel property of a TBitmapData instance.
Once the qr code is generated, to convert it to a bitmap image, in FireMonkey:
VCL’s Canvas.StretchDraw to FMX’s Canvas.DrawBitmap
There’s no StrecthDraw in FMX’s Canvas class. There’s DrawBitmap. StretchDraw by default does no antialiasing. FMX does. So I had to play a little until I was able to make it work correctly.
I’ve decided to use TImage and not TPaintBox as I was simply not able to make TPictureBox in FireMonkey draw what I wanted 🙁
Using TImage, the code to get/display the generated QR Code is as follows:
Aliasing – Do Not Need It!
By default, in FMX, when using DrawBitmap to resize it, antialiasing is used by default. There are two properties you need to set to ensure a bigger copy of your (small) qr code is drawn pixel-copy-perfect.
In a FireMonkey Desktop application, this works as expected.
On FireMonkey Mobile it does not 🙁 – the resized image is still blurred (antialiasing used).
That’s it. QR Codes generation in FireMonkey – both desktop and mobile!
Download the FMX version of DelphiZXIngQRCode.pas: FMX-DelphiZXIngQRCode
Comments are welcome (even more if you know how to resize a bitmap in FireMonkey on mobile without antialiasing)!
Источник
Delphi android qr code
ZXing Barcode Scanning Library for Delphi XE to 10.4 Sydney
ZXing.Delphi is a native Object Pascal library that is based on the well known open source Barcode Library: ZXing (Zebra Crossing). This port is based on .Net Redth port of ZXing and the Java one. This is I think the first native FireMonkey barcode lib. It is aimed at all of the FireMonkey mobile platforms and, starting from v3.1, it fully supports also Windows VCL applications (no dependencies on FMX.Graphics unit).
With this library you can scan with native speed without the use of linking in external libraries and avoid compatibility issues and dependencies. It is fast.
Its compatible with in Delphi XE7 — 10 Sydney and tested with IOS 8.x, 9.x, 10.x, 11.x, 12.x, Android, Windows 32/64 and OSX. The goal of ZXing.Delphi is to make scanning barcodes effortless, painless, fast and build within your FireMonkey or native Windows (VCL or Firemonkey) applications.
Just include the source files and add it in your existing projects and build the ZXing.Delphi source within your projects.
The standard camera component is, I think too slow for Android and IOS. You need to find a third party product or cook your own for a smooth experience.
1D product | 1D industrial | 2D |
---|---|---|
UPC-A | Code 39 | QR Code |
UPC-E | Code 93 | Data Matrix (Center images only) |
EAN-8 | Code 128 | |
EAN-13 | ITF |
- Native compiled barcode scanning for all VCL and FireMonkey platforms (IOS/Android/Windows/OSX).
- 100% free. No license fees. Just free.
- Speed
- Simple API
- Unit tests provided
- Test projects provided
- QRCode 64bit Android and IOS fix (Issue #93 and #62)
- Some memleak fixes and simplified Advanced test app.
- In ‘Advanced demo’ added Rio compatible Android camera optimizing library (thanks to E. van Bilsen).
- Fixed missing files for ‘advanced test demo app’, due to incompatibility with the external used libFastUtils.a and libfastutils-android.a it is not supported for Rio and Android.
- Added in ‘advanced test demo app’ new Rio / Android 7+ code for the new permission model.
- Changes in demo app. Asking Permissions to mobile users.
- Fixed QRCode bug and QR Memleak (thanks to C. Pradelli)
- Fixed a QRCode bug. Did not find the QRCode in some cases. Bugfix: https://github.com/Spelt/ZXing.Delphi/issues/65
- Added an advanced test app. Featuring faster camera, sound, barcode marker,warning for slow camera and a cool HUD. It makes use of huge camera performance tweak. See Readme in the uMain.pas and https://quality.embarcadero.com/browse/RSP-10592
- Little cleanup
v3.3.1 Date: 2017/01/08 (Thanks for Nano103)
v3.3 Date: 2016/12/10 (Thanks for Nano103 for adding Code 39)
- Added UPC-A, UPC-E, Code 39
- Now Delphi is listed at the official zxing page: https://github.com/zxing/zxing
- Added tip section.
v3.2 Date: 2016/11/27
- Added EAN8, EAN13 (many requests)
- v3 becomes master branch
v3.1 Date: 2016/06/28 (Super many thanks to: Carlo Sirna)
- Added VCL support (via IFDEF USE_VCL_BITMAP).
- Memleak fixes for old gen compilers (win32/win64).
- Fix: QRCode ECI character set + extra unit test.
- Added ‘Load Image from file’ command in test project.
- UTF-8 fixed bug + added unit test
- Some other bug fixes.
v3.0 Date: 2016/04/28 (Great many thanks to: Kai Gossens and Raphael Büchler)
- Massive folder restructuring
- Added DataMatrix (centered only).
- ResultPoint event added.
- Support for inverted 1D/2D code types.
- Better OneDReader scan strategy
- Redesigned the file/folder structure for better namespacing.
- Simplification of adding readers to the TMultiformatReader (just add all your readers here)
- Small improvements.
v2.4 Date: 2016/04/06
- Fix in Code128 where code did not scan at all sometimes.
v2.3 Date: 2016/02/27
- Fixed leaks.
- Android added to compatibility list.
v2.2 Date: 2016/02/21
- Fixed IOS crash bug on 32bit only (ITF related).
v2.1 Date: 2016/01/29
- Implemented ITF (thanks p. b. Hofstede!) + unit test.
- Fixed small bug.
v2.0 Date: 2015/11/30
- Implemented QR-Codes + unit test.
v1.1 Date: 2015/7/11
- Implemented Code 93 + unit test.
- Init upload
- Base classes 1D barcode implemented.
- Implemented Code 128 + unit test.
Tips — How to optimize an already fast library.
- Try not to scan every incoming frame.
- Use autoformat scanning with care, with automatic on every frame is passed to every barcode format. For example: If you want to scan only EAN-8, set the scan format for only EAN-8.
- For mobile: try not to scan every frame, skip every n frame. Scanning 4 frames in a second should be good for most purposes. Safes CPU and battery.
- For mobile: try setting your camera not to a high resolution. 640×480 is for most purposes perfect. More resolutions means more pixels to scan means slower. Saves CPU and battery.
Although it works extremely well, we still miss a few barcodes.For me there is no immediate need yet for me to implement more types but I like to add all of them! For that I need your help!
The base classes are already implemented so if you need to have another Barcode like Code39 (already done 🙂 ) you can see the C# source here: https://github.com/Redth/ZXing.Net.Mobile/blob/master/src/ZXing.Net/oned/Code39Reader.cs and convert it to Pascal. It’s pretty easy (or just ask and I convert the raw classes for you).
If you want to help: Let us/me know which barcode you planning to implement. There is no point in converting barcodes multiple times 🙂
‘What is different compared to the original source and what do I need to know if I implement a barcode?’ How did you do it?
- I convert C# files to pascal via:
- Build it in .NET
- Decompile it with ‘Reflector 6’ (which has a Delphi decompile function) to Delphi.NET
- Copy and paste the files to the project.
- Convert the source from Delphi.Net
- I made use of generic array lists. This is easier and strongly typed.
- I stayed at the architecture and directory structure as implemented in the .Net source.
- There is a lot of bit shifting going around. Left bit shifting is the same as in C# but right bit shifing is not! I made a helper for this: TMathUtils.Asr
The simplest example of using ZXing.Delphi looks something like this:
Include all the files in your project or use search path like included test application
- Add uses: ScanManager, ZXing.BarcodeFormat, ZXing.ReadResult.
- Add var FScanManager, FReadResult.
Of course the real world is not that simple. To leave your app responsive while scanning you need to run things in parallel. I created a test app to show you how just to do that. Its included. It makes use of the new Firemonkey parallel lib. In the testApp the resolution of the camera is set to medium (FMX.Media.TVideoCaptureQuality.MediumQuality) on my iPhone 6. This is only possible since XE8 and equivalent Appmethod. Its also good to mention that how higher the resolution the more time it takes to scan a bitmap. Some scaling could probably work too.
Andrea Magni has a very nice blog post about an Android ZXing example from a training excerise of his. You can find it here.
ZXing.Delphi is a project that I’ve put together with the work of others. So naturally, I’d like to thank everyone who’s helped out in any way. Those of you I know have helped I’m listing here, but anyone else that was involved, please let me know!
- The ZXing main project author — Sean Owen.
- J. Dick at Redth at https://github.com/Redth/ZXing.Net.Mobile
- Carlo Sirna
- P. B. Hofstede
- Kai Gossens
- Raphael Büchler
- Nano103
ZXing.Delphi is released under the Apache 2.0 license. ZXing.Delphi can be found here:https://github.com/Spelt/ZXing.Delphi A copy of the Apache 2.0 license can be found here: http://www.apache.org/licenses/LICENSE-2.0
ZXing is released under the Apache 2.0 license. ZXing can be found here: http://code.google.com/p/zxing/ A copy of the Apache 2.0 license can be found here: http://www.apache.org/licenses/LICENSE-2.0
ZXing.Net is released under the Apache 2.0 license. ZXing.Net can be found here: http://code.google.com/p/zxing/ A copy of the Apache 2.0 license can be found here: http://www.apache.org/licenses/LICENSE-2.0
About
ZXing Barcode Scanning object Pascal Library for Delphi VCL and Delphi Firemonkey
Источник
ScannerMApp: a QR/barcode scanner app with Delphi, ZXing and TFrameStand
It is plenty out there of barcode/QR code scanner apps (both on Android Play Store and Apple AppStore [and iOS 11 include native code scanner in the camera app]) so it may seem there is no need to build a new one but this is not true!
In this blog post I will describe how I built a barcode scanner app (ScannerMApp, currently available in a beta stage on the Play Store) in Delphi using the Edward Spelt’s Delphi port of the ZXing library and my TFrameStand component.
The project only depends on Delphi (10.2 Tokyo used) and two OSS libraries: ZXing and TFrameStand. Full source code of ScannerMApp is available on my GitHub.com repository.
Video demo
Sometimes, a video is better than a thousand words: here it is a 45 seconds video showcasing ScannerMApp 🙂
Introduction
QR codes (barcodes, in general) are really handy when you need to join the physical world with the digital one, simply put a QR code on an item or in a physical place and that item/place is now digitally tagged (and you can take advantage of this in your applications).
While preparing material for the last Delphi mobile training course I gave, I received questions about building a solution to read barcodes / QR codes in a Delphi mobile app. I already covered this argument on my blog, at XE5 time and later with XE7, but with a different approach: launch a third-party barcode scanner app and get results through clipboards or Android intent infrastructure.
This time I tried to have more control and decided to integrate a library for QR code recognition directly into my FMX app. This approach has some advantages like:
- it does not create a dependency with a third party app (or/and the way to communicate with it);
- it gives you full control on all details of the scanning phase: you can provide a bitmap to the library and ask for a search of desired code types so you may want to get a frame from a camera (deciding resolution if you care), add some pre-processing if needed and get some additional informations about the result, like the exact position of the found code in the bitmap;
- if the barcode recognition library is written 100% Delphi code, you achieve a great portability of your app through different platforms (Android, iOS, Windows, Mac OS X and Linux!)
So I decided to build this FMX application trying to provide a tangible example about how to structure a simple Delphi mobile app that access sensors (camera can be considered a sensor), stores values and present them to the user through a minimal UI.
Scanning barcodes
The ZXing project is the most popular open source barcode scanning library in Java and has been ported to different languages (C++, .Net C#, php, Objective-C, python, JavaScript and … Delphi! 🙂 ).
Thanks to Edward Spelt and his Delphi library (that I would suggest to be added here) we all can benefit and easily build barcode-enabled multi-platform applications with Delphi!
The library is very easy to use, fast, has good support to all major barcode formats and has been recently updated with a farther performance improvement tied to inverted barcode recognition (now optional, so you can save time if you don’t need to read inverted barcodes).
I want to thank Edward for the kind suggestions (and corrections to my code) he gave me during the development of this app.
ZXing.Delphi on GitHub.com
You can obviously have a look to ZXing.Delphi demos and to the source code of my ScannerMApp and see all the details on how the library works and has been used.
For the ScannerMApp, I decided to implement two use cases:
- start the device camera (using a low resolution setting), grab each available frame but scan only each X milliseconds (currently X=133, to give something like 7 attempts per second);
- pick a picture from the library (or filesystem on Desktop platforms) and scan once (generally sufficient since there is no focusing problems and of course no targeting is possible).
The app structure
I tend to structure my Delphi mobile apps using datamodules, a single main form and several frames. Using TFrameStand is easy to orchestrate how the frames get shown to compose the user experience.
Here is a simple diagram of ScannerMApp:
All the important code is in the main datamodule (MainDM) including the TCameraComponent used to grab frames from the device camera, the TFDMemTable used as storage for result data and all the ZXing.Delphi related code.
Each frame is used to present a different piece of UI to the user, reflecting the app status and data available:
- TScanningFrame is responsible to help the user acquire the barcode by painting the camera’s frames on a TRectangle (faster than a TImage) and hosts an informative label about current camera resolution (and FPS even if it seems to be hardcoded in Android) and a button to toggle the torch mode (where available) that may help when there is no sufficient light in the room; during the scanning, you may see some TRectangle(s) being drawn over the camera’s frame, to indicate the ZXing.Delphi library detected something possibly being a barcode there.
- TDataFrame has a TListView with DynamicAppearance and is used to present to the user the so far scanned barcodes, including details per each item like a thumbnail, the barcode format, the content and a counter of how many times that specific barcode has been scanned (since the start of the app); clicking on an item will lead to the details (see next point in this list);
- TScanResultFrame is used to present the user the successfully scanned barcode informations like format, date of (first) acquisition, a picture of the frame with some markers indicating the barcode position and a couple of actions to let the user delete the current item or share the content of the barcode through the system’s ShareSheet;
- TInfoFrame (not listed in the above diagram) is used to show a simple credits layout about the app and libraries used.
On the MainForm you can see the TFrameStand instance that will orchestrate the UI through all the app.
I decided to take advantage of the built-in System.Messaging publish/subscribe mechanism using the default TMessageManager to send and receive messages through all the app. This way, the dependencies across the modules (forms, datamodule, frames) of the app are minimal (many knows the MainDM, the MainForm knows most of the frames but no crossed dependecies) and code can be properly separated (no UI code in the datamodule, no application code in the UI frames). You can see, in the above diagram, who is publishing messages and who is subscribed to them by looking at the small mail icon (green = subscribed, red = publish). As you can see in the code of Data.Main.pas and here below, a bunch of custom messages have been defined and used across the app:
- each time a frame is available from the device camera (see TMainDM.CameraComponent1SampleBufferReady), a TCameraBufferMessage is sent (and the TScanningFrame, subscribed to that message, will receive the bitmap to be shown to the user);
- each time the ZXing.Delphi library detects a possible result point of a barcode (during scan) a TScanPointMessage is sent (and TScanningFrame will inform the user by drawing a rectangle over the frame);
- when a barcode is successfully found, the MainDM will send a TScanResultMessage and the MainForm, the MainDM and the TDataFrame will be informed about the newly available result (the MainForm will ensure the user can see the TDataFrame, the MainDM will store the result in the TFDMemTable and the TDataFrame will refresh the ListView).
Technologies
It has been a pleasure to build this app, using a lot of different technologies included in Delphi or available as OpenSource projects.
- RTL provides (among many other features) the System.Messaging mechanism
- FMX provides(among many other features) easy access to the device camera
- FireDAC is used to easily store results (using a memory table and including bitmaps)
- LiveBindings are used to bind the memory table to the TListview on the TDataFrame
- Parallel programming library is used to perform barcode scanning in the background of the application, ensuring a great user experience
- ZXing.Delphi implements barcode detection and decoding
- TFrameStand orchestrates the UI, providing visual continuity and nice effects/transitions easily
What’s next and conclusion
As I said, this app was initially built to be shown and explained in a training course of mine (as a proof of concept), then I tried to polish it a bit, improve performance and user experience (thanks again to Edward Spelt for some hints and suggestions) and now I am releasing it as an example for all Delphi developers. Of course it can be greatly improved in some areas and of course it is far from perfect but seems nice so far 😉
There are a few things I’d like to do:
- register the app for SEND action intent-filter on Android (would make ScannerMApp to show up in the ShareSheet, also from other applications). This is a work in progress but not yet finished.
- need to test a bit on iOS (if anyone can give feedback it would be great)
- define a storage strategy (locally save the memory table or send data to a remote server, depending on needs)
- provide a sound feedback on successful scans
- filtering desired barcode format (the user may be looking only for QR codes or EAN13… this should improve precision in result acquisition reducing false positives)
I hope you’ll enjoy this example as I do! I think this is a good example how easy it is to build a not-so-trivial mobile app with Delphi (and have it running on multiple platforms!).
Источник