Import->Flex Project : select the 'client' folder)
- uncheck 'Use default location' and press Finish
- import the zxing library project (File->Import->FlexProject : select the 'core' folder)
- uncheck 'Use default location' and press Finish
- Right click the 'zxing client' project to select Properties
- goto the 'Flex Build Path' section and select the 'Source path' tabsheet
- click the 'Add Folder' button and select the 'src' directory in the 'core' project folder
Now the client will use the zxing source files directly to build the application.
Any updates in the library will then automatically be used by the client
An an alternative would be to generate a SWC library file for the zxing.
For more details, join the zxing project and please commit your bugfixes to the zxing repository.
http://zxing.google.com
Bas Vijfwinkel
Notes :
- This project should compile with Flexbuilder 3.0 in combination with Flash10.
If you do not need access to the local filesystem, Flash 9 should be sufficient to run this application.
- I have omitted some very specific settings in this example application (e.g. the extended mode for code39/128 barcodes).
The zxing library does handle these barcodes correctly if you set these modes correctly.
- Actionscript is not very good at handling character sets with various encodings (used in e.g. in QRCodes).
UTF8 and ShiftJIS encodings seem to work but I have not been able to test other character encodings.
- Great performance improvements can be made but this needs quite some altering of the
current library.
In order to keep the library as much in line with the original library for future updates and bugfixes,
I have choosen not to implement those improvements here. I believe maintainability has a higher priority
than performance at this moment
I have introduced some extra classes in the
com/google/zxing/common/flexdatatypes folder that match some of the default Java classes.
- If you encounter bugs (and hopefully solutions) please join the zxing project and commit your fixes to
the repository. Zxing project members are always willing to assist you if you're not familiar with repositories.
- The Zxing project files are licensed under the Apache License, Version 2.0 (the "License");
You may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
- When using a webcam make sure you set the resolution to at least 300x300 with the setMode method of the Camera object.
The default 160x120 resolution is too low for recognition of most barcodes.
*/
import mx.core.BitmapAsset;
import com.google.zxing.common.flexdatatypes.HashTable;
import flash.net.FileReference;
import flash.display.Bitmap;
import flash.display.*;
import flash.net.URLRequest;
import flash.events.Event;
import mx.controls.Alert;
import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.ByteMatrix;
import com.google.zxing.client.result.ParsedResult;
import com.google.zxing.client.result.ResultParser;
import com.google.zxing.DecodeHintType;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.BufferedImageLuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
private var fileRef:FileReference;
private var myReader:MultiFormatReader;
private var hints:HashTable;
private var myWriter:MultiFormatWriter;
public function init():void
{
// initialise the generic reader
myReader = new MultiFormatReader();
}
public function decodeImage():void
{
// did the user select an image?
if (this.img.source != "")
{
// show a message we are decoding
this.resulttextarea.text = "*** decoding ***"
try
{
// is the image valid?
if (img.content != null)
{
// try to decode the image
this.decodeBitmapData((img.content as Bitmap).bitmapData,img.contentWidth, img.contentHeight);
}
else
{
// invalid image
this.resulttextarea.text = "no image selected";
}
}
catch(E:Error)
{
this.resulttextarea.text = "*** Error in image data***"
}
}
}
public function decodeBitmapData(bmpd:BitmapData, width:int, height:int):void
{
// create the container to store the image data in
var lsource:BufferedImageLuminanceSource = new BufferedImageLuminanceSource(bmpd);
// convert it to a binary bitmap
var bitmap:BinaryBitmap = new BinaryBitmap(new GlobalHistogramBinarizer(lsource));
// get all the hints
var ht:HashTable = null;
ht = this.getAllHints()
var res:Result = null;
try
{
// try to decode the image
res = myReader.decode(bitmap,ht);
}
catch(e:Error)
{
// failed
}
// did we find something?
if (res == null)
{
// no : we could not detect a valid barcode in the image
this.resulttextarea.text = "<>";
if (!this.bc_tryharder.selected)
{
this.resulttextarea.text = "<>";
}
}
else
{
// yes : parse the result
var parsedResult:ParsedResult = ResultParser.parseResult(res);
// get a formatted string and display it in our textarea
this.resulttextarea.text = parsedResult.getDisplayResult();
}
}
public function getAllHints():HashTable
{
// get all hints from the user
var ht:HashTable = new HashTable();
if (this.bc_QR_CODE.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.QR_CODE); }
if (this.bc_DATAMATRIX.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.DATAMATRIX); }
if (this.bc_UPC_E.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.UPC_E); }
if (this.bc_UPC_A.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.UPC_A); }
if (this.bc_EAN_8.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.EAN_8); }
if (this.bc_EAN_13.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.EAN_13); }
if (this.bc_CODE_39.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.CODE_39);}
if (this.bc_CODE_128.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.CODE_128); }
if (this.bc_PDF417.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.PDF417); }
if (this.bc_ITF.selected) { ht.Add(DecodeHintType.POSSIBLE_FORMATS,BarcodeFormat.ITF); }
if (this.bc_tryharder.selected) { ht.Add(DecodeHintType.TRY_HARDER,true); }
return ht;
}
public function clearImage():void
{
// remove the image
this.img.source = null;
this.resulttextarea.text = "";
}
public function selectFile():void
{
// file open menu
fileRef = new FileReference();
var fileFilter4:FileFilter = new FileFilter('JPG','*.jpg');
var fileFilter1:FileFilter = new FileFilter('PNG','*.png');
var fileFilter2:FileFilter = new FileFilter('GIF','*.gif');
var fileFilter3:FileFilter = new FileFilter('All files','*.*');
fileRef.addEventListener(Event.SELECT, selectHandler);
fileRef.addEventListener(Event.COMPLETE,completeHandler);
fileRef.browse([fileFilter4,
fileFilter1,
fileFilter2,
fileFilter3]);
}
public function selectHandler(event:Event):void
{
// try to load the image
fileRef.removeEventListener(Event.SELECT, selectHandler);
fileRef.load();
}
public function completeHandler(event:Event):void
{
// image loaded succesfully
fileRef.removeEventListener(Event.COMPLETE,completeHandler);
img.load(fileRef.data);
}
public function selectNone():void
{
// remove all hints (except the try harder hint)
this.bc_QR_CODE.selected = false;
this.bc_DATAMATRIX.selected = false;
this.bc_UPC_E.selected = false;
this.bc_UPC_A.selected = false;
this.bc_EAN_8.selected = false;
this.bc_EAN_13.selected = false;
this.bc_CODE_128.selected = false;
this.bc_CODE_39.selected = false;
this.bc_ITF.selected = false;
}
private function videoDisplay_creationComplete():void
{
// try to attach the webcam to the videoDisplay
var camera:Camera = Camera.getCamera();
if (camera)
{
if ((camera.width == -1) && ( camera.height == -1))
{
// no webcam seems to be attached -> hide videoDisplay
videoDisplay.width = 0;
videoDisplay.height = 0;
this.videoDisplayLabel.visible = true;
this.buttonBox.visible = false;
}
else
{
// webcam detected
// change the default mode of the webcam
camera.setMode(350,350,5,true);
videoDisplay.width = camera.width;
videoDisplay.height = camera.height;
this.videoDisplayLabel.visible = false;
this.buttonBox.visible = true;
videoDisplay.attachCamera(camera);
}
} else {
Alert.show("You don't seem to have a webcam.");
}
}
private function decodeSnapshot():void
{
// try to decode the current snapshpt
var bmd:BitmapData = new BitmapData(this.videoDisplay.width, this.videoDisplay.height);
bmd.draw(videoDisplay);
this.decodeBitmapData(bmd, this.videoDisplay.width, this.videoDisplay.height);
}
public function generateQRCode():void
{
// read input string
var contents:String = this.QRINput.text;
myWriter = new MultiFormatWriter();
try
{
// try to encode the string
var result:ByteMatrix = (myWriter.encode(contents,BarcodeFormat.QR_CODE,300,300)) as ByteMatrix;
}
catch (e:Error)
{
Alert.show('An error occurred during the encoding process');
return;
}
// try to generate an image with the result data
var bmpd:BitmapData = new BitmapData(300, 300, false, 0x009900);
var bmp:Bitmap = new Bitmap(bmpd);
this.QRImage.source = bmp;
for (var h:int=0;h<300;h++)
{
for (var w:int=0;w<300;w++)
{
if (result._get(w,h) == 0)
{
bmpd.setPixel(w,h, 0);
}
else
{
bmpd.setPixel(w,h, 0xFFFFFF);
}
}
}
}
public function generateEANBarcode():void
{
var name:String = "";
var barcodeType:BarcodeFormat = null;
var inputlength:int = 0;
// set the correct parameters
if (this.EAN8.selected)
{
name = "EAN8";
barcodeType = BarcodeFormat.EAN_8;
inputlength = 8;
}
else
{
name = "EAN13";
barcodeType = BarcodeFormat.EAN_13;
inputlength = 13;
}
var resultBits:Array = null;
var contents:String = this.EANINput.text;
// do some checking
if (contents.length > inputlength)
{
Alert.show(name+' can only contain '+inputlength+' digits');
return;
}
var counter:int=0;
while(counter < contents.length)
{
var cc:int = contents.charCodeAt(counter);
if ((cc<0x30) || (cc>0x39))
{
Alert.show("EAN barcodes can only contain digits");
return;
}
counter++;
}
while (contents.length < inputlength) { contents = "0" + contents; }
this.EANINput.text = contents;
myWriter = new MultiFormatWriter();
try
{
// try to generate the data for the barcode
var result:ByteMatrix = myWriter.encode(contents,barcodeType) as ByteMatrix;
}
catch (e:Error)
{
Alert.show("An error occured when making the barcode");
}
resultBits = new Array(result.height());
for (var i:int=0;i