Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit 1550713dbd89ccf42f0b0286ab8c35b3ac849e9f @yanbe committed Nov 9, 2008
BIN .DS_Store
Binary file not shown.
@@ -0,0 +1,2 @@
+all:
+ mxmlc QRCodeReader.as
@@ -0,0 +1,69 @@
+package {
+ import flash.display.*;
+ import flash.events.*;
+ import flash.geom.*;
+ import flash.media.*;
+ import flash.text.*;
+ import flash.utils.*;
+ import qrcode.*;
+
+ public class QRCodeReader extends Sprite {
+ private var video:Video;
+ private var pixels:BitmapData;
+ private var debug:BitmapData;
+ private var text:TextField;
+
+ public function QRCodeReader() {
+ stage.scaleMode = StageScaleMode.NO_SCALE;
+ stage.align = StageAlign.TOP_LEFT;
+
+ var camera:Camera = Camera.getCamera();
+
+ if (camera!=null) {
+ camera.setMode(640, 480, 30);
+ video = new Video(camera.width,camera.height);
+ video.attachCamera(camera);
+ pixels = new BitmapData(video.width, video.height, false, 0x00000000);
+ createBitmap(pixels, 0, 0);
+ debug = new BitmapData(video.width, video.height, false, 0x00000000);
+ createBitmap(debug, 640, 0);
+ addEventListener(Event.ENTER_FRAME, onEnterFrame);
+ text = createTextField(0, 480, 640, 480);
+ }
+ }
+
+ private function createTextField(x:Number, y:Number, width:Number,
+ height:Number):TextField {
+ var result:TextField = new TextField();
+ result.x = x;
+ result.y = y;
+ result.width = width;
+ result.height = height;
+ addChild(result);
+ return result;
+ }
+
+ private function createBitmap(pixels:BitmapData, x:int, y:int):Bitmap {
+ var result:Bitmap = new Bitmap(pixels);
+ result.x = x;
+ result.y = y;
+ result.width = pixels.width;
+ result.height = pixels.height;
+ addChild(result);
+ return result;
+ }
+
+ private function onEnterFrame(event:Event):void {
+ pixels.draw(video);
+ var result:DecodeResult = QRCodeDecoder.decode(pixels);
+ text.text = result.text;
+ debug.fillRect(new Rectangle(0,0,debug.width,debug.height), 0x00000000);
+ debug.draw(result.debug);
+ for each(var line:Object in result.across) {
+ for (var i:int=0; i<line.offset; i++) {
+ debug.setPixel(line.end.x-i, line.end.y, 0x00ff00);
+ }
+ }
+ }
+ }
+}
Binary file not shown.
0 README
No changes.
@@ -0,0 +1,14 @@
+package qrcode {
+ import flash.geom.*;
+ import flash.display.*;
+
+ public class DecodeResult {
+ public var version:uint;
+ public var errorCorrectionLevel:uint;
+ public var text:String;
+ public var debug:BitmapData;
+ public var across:Array;
+ public var pos:Object = {leftTop:Point, rightTop:Point,
+ leftBottom:Point, rightBottom:Point};
+ }
+}
@@ -0,0 +1,64 @@
+package qrcode {
+ import flash.display.*;
+ import flash.geom.*;
+
+ public class FinderPattern {
+ public static function findPattern(pixels:BitmapData):Object {
+ var linesAcross:Array = findLinesAcross(pixels);
+ var centors:Array = findCenters(linesAcross);
+ return {leftTop:new Point(10,10),
+ rightTop:new Point(200,10),
+ leftBottom:new Point(10,200),
+ across:linesAcross};
+ }
+ private static function findLinesAcross(pixels:BitmapData):Array {
+ var reference:Array = new Array(1, 1, 3, 1, 1);
+ var referenceSum:int = 7; //1+1+3+1+1
+ var recent:Array = new Array();
+ var linesAcross:Array = new Array();
+ for (var y:int=0; y<pixels.height; y++) {
+ var last:int = 0;
+ var current:int = 0;
+ var length:int = 0;
+ for (var x:int=0; x<pixels.width; x++) {
+ current = pixels.getPixel(x, y);
+ if (current==last) {
+ length++;
+ } else {
+ if (recent.push(length) > reference.length) {
+ recent.shift();
+ }
+ if (current==0) { //white->black transision
+ } else { //black->white transition
+ if (recent.length==reference.length) {
+ var recentAverage:int = 0;
+ var recentSum:int = 0;
+ var i:int;
+ for (i=0; i<recent.length; i++) {
+ recentSum+=recent[i];
+ }
+ recentAverage = recentSum/referenceSum;
+ for (i=0; i<recent.length; i++) {
+ var t:int = reference[i]*recentAverage;
+ if ((recent[i]<t*0.5) || (recent[i]>t*2)) {
+ break;
+ }
+ }
+ if (i==recent.length) {
+ linesAcross.push({
+ end:new Point(x-1,y),
+ offset:recentSum});
+ }
+ }
+ }
+ length = 1;
+ last = current;
+ }
+ :
+ recent = new Array();
+ length = 0;
+ }
+ return linesAcross;
+ }
+ }
+}
@@ -0,0 +1,51 @@
+package qrcode {
+ import flash.display.*;
+ import flash.geom.*;
+ import flash.utils.*;
+
+ public class QRCodeDecoder {
+ public static function decode(pixels:BitmapData):DecodeResult {
+ var b:BitmapData = createBinaryImage(pixels);
+ var patterns:Object = FinderPattern.findPattern(b);
+ var result:DecodeResult = new DecodeResult();
+ result.across = patterns.across;
+ result.pos.leftTop = patterns.leftTop;
+ result.pos.rightTop = patterns.rightTop;
+ result.pos.leftBottom = patterns.leftBottom;
+ result.text = "("+result.pos.leftTop.x+", "+result.pos.leftTop.y+") "+result.across.length;
+ result.debug = b;
+ return result;
+ }
+
+ private static function createBinaryImage(pixels:BitmapData):BitmapData {
+ var nDivision:int = 4;
+ var b:BitmapData = new BitmapData(pixels.width, pixels.height);
+
+ var areaWidth:int=b.width/nDivision;
+ var areaHeight:int=b.height/nDivision;
+
+ for (var ay:int=0; ay<nDivision; ay++) {
+ for (var ax:int=0; ax<nDivision; ax++) {
+ var rectangle:Rectangle = new Rectangle(ax*areaWidth, ay*areaHeight,
+ areaWidth, areaHeight);
+
+ var samples:ByteArray = pixels.getPixels(rectangle);
+ var i:int;
+ var offset:int;
+ var threshold:uint=0;
+ for (i=0,offset=0; i<samples.length; i++,
+ offset+=samples.length/(nDivision*nDivision)) {
+ threshold+=samples[offset] & 0xff;
+ }
+ threshold = threshold/i+0x40;
+ var color:uint = 0x00000000;
+ var maskColor:uint = 0x000000ff;
+
+ b.threshold(pixels, rectangle, new Point(ax*areaWidth, ay*areaHeight), "<=", threshold, color,
+ maskColor, false);
+ }
+ }
+ return b;
+ }
+ }
+}

0 comments on commit 1550713

Please sign in to comment.