AS3 QR Code Generator


/ Published in: ActionScript 3
Save to your folder(s)

This makes use of http://www.minimalcomps.com, https://github.com/mikechambers/as3corelib and http://alivepdf.bytearray.org


Copy this code and paste it in your HTML
  1. // Useful Resources
  2. //
  3. // http://active.tutsplus.com/tutorials/actionscript/quick-tip-using-a-php-proxy-to-load-assets-into-flash/
  4. // http://blog.juanbonfante.com/?p=272
  5. // http://alivepdf.bytearray.org/
  6. // http://blog.unthinkmedia.com/2008/09/05/exporting-pdfs-in-flex-using-alivepdf/
  7. // http://lucamezzalira.com/2009/02/28/create-pdf-in-runtime-with-actionscript-3-alivepdf-zinc-or-air-flex-or-flash/
  8.  
  9. package
  10. {
  11. import flash.display.Loader;
  12. import flash.display.MovieClip;
  13. import flash.display.Sprite;
  14. import flash.events.Event;
  15. import flash.display.Shape;
  16. import flash.events.HTTPStatusEvent;
  17. import flash.events.IOErrorEvent;
  18. import flash.events.TextEvent;
  19. import flash.geom.Rectangle;
  20. import flash.net.URLRequest;
  21. import flash.display.Bitmap;
  22. import flash.net.URLVariables;
  23. import flash.text.TextFormat;
  24. import flash.text.TextField;
  25. import flash.text.TextFormatAlign;
  26. import flash.text.TextFieldAutoSize;
  27. import flash.net.navigateToURL;
  28. import flash.system.LoaderContext;
  29. import flash.system.Security;
  30. import flash.display.BitmapData;
  31. import flash.utils.ByteArray;
  32. import flash.net.URLRequestHeader;
  33. import flash.net.URLRequestMethod;
  34. import flash.printing.PrintJob;
  35. import flash.net.FileReference;
  36.  
  37. // http://www.minimalcomps.com
  38. import com.bit101.components.Text;
  39. import com.bit101.components.HUISlider;
  40. import com.bit101.components.PushButton;
  41. import com.bit101.components.Label;
  42.  
  43. // https://github.com/mikechambers/as3corelib
  44. import com.adobe.images.JPGEncoder;
  45. import com.adobe.images.PNGEncoder;
  46.  
  47. // http://alivepdf.bytearray.org/
  48. import org.alivepdf.pdf.PDF;
  49. import org.alivepdf.layout.Orientation;
  50. import org.alivepdf.layout.Size;
  51. import org.alivepdf.layout.Unit;
  52. import org.alivepdf.display.Display;
  53. import org.alivepdf.saving.Method;
  54. import org.alivepdf.layout.Resize;
  55. import org.alivepdf.layout.Mode;
  56. import org.alivepdf.layout.Position;
  57.  
  58. [SWF(width = '500', height = '500', backgroundColor = '#FFFFFF', frameRate = '25')]
  59.  
  60. /**
  61. * ...
  62. * @author Adrian Parr
  63. */
  64. public class Main extends Sprite
  65. {
  66.  
  67. [Embed(source="../assets/title.png")]
  68. private var TitleGraphic:Class;
  69.  
  70. [Embed(source="../assets/loading_anim.swf")]
  71. private var LoadingAnim:Class;
  72.  
  73. private static const _serversideProxyUrl:String = "proxy.php";
  74. private static const _googleUrl:String = "http://chart.apis.google.com/chart";
  75. private static const _imageFilename:String = "qr_code";
  76. private static const _createPngFilePhpUrl:String = "png_encoder_download.php";
  77. private static const _createJpegFilePhpUrl:String = "jpg_encoder_download.php";
  78. private static const _pdfFilename:String = "qr_code.pdf";
  79. private static const _printA4width:int = 580;
  80. private static const _printA4height:int = 830;
  81. private static const _pdfA4width:int = 540;
  82. private static const _pdfA4height:int = 790;
  83.  
  84. private var _loadingAnim:MovieClip;
  85.  
  86. private var _border:Shape;
  87. private var _borderColour:uint = 0x036CB4;
  88. private var _borderWidth:uint = 1;
  89. private var _borderAlpha:Number = 1;
  90. private var _controlsHeight:int = 100;
  91. private var _controls:Sprite;
  92.  
  93. private var _qrLoader:Loader;
  94. private var _urlVars:URLVariables;
  95. private var _urlRequest:URLRequest;
  96. private var _url:String = "";
  97. private var _size:int;
  98.  
  99. private var _urlText:Text;
  100. private var _dimensionsSlider:HUISlider;
  101. private var _generateBtn:PushButton;
  102. private var _savePngBtn:PushButton;
  103. private var _saveJpegBtn:PushButton;
  104. private var _printBtn:PushButton;
  105. private var _pdfBtn:PushButton;
  106. private var _defaultSize:int = 200;
  107.  
  108. private var _qrCodeBitmapData:BitmapData;
  109. private var _errorTxt:TextField = new TextField();
  110. private var _printTemplate:Sprite;
  111.  
  112.  
  113. public function Main():void
  114. {
  115. if (stage) init();
  116. else addEventListener(Event.ADDED_TO_STAGE, init);
  117. }
  118.  
  119.  
  120. private function init(e:Event = null):void
  121. {
  122. removeEventListener(Event.ADDED_TO_STAGE, init);
  123.  
  124. var bgRect:Shape = new Shape();
  125. bgRect.graphics.beginFill(0xCCCCCC, 1);
  126. bgRect.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
  127. bgRect.graphics.endFill();
  128. addChild(bgRect);
  129.  
  130. createControls();
  131.  
  132. _border = new Shape();
  133. _border = drawBorder(_borderColour, _borderWidth, _borderAlpha);
  134. addChild(_border);
  135.  
  136. _qrLoader = new Loader();
  137. _qrLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onQrLoader_COMPLETE);
  138. _qrLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onQrLoader_IO_ERROR);
  139. _qrLoader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, onQrLoader_HTTP_STATUS);
  140.  
  141. _loadingAnim = new LoadingAnim();
  142. _loadingAnim.visible = false;
  143. _loadingAnim.alpha = 0.7;
  144. _loadingAnim.x = stage.stageWidth / 2 - _loadingAnim.width / 2;
  145. _loadingAnim.y = ((stage.stageHeight-_controlsHeight) / 2) - (_loadingAnim.height / 2) + _controlsHeight;
  146. addChild(_loadingAnim);
  147.  
  148. _printTemplate = new Sprite();
  149. _printTemplate.graphics.beginFill(0xFFFFFF, 1);
  150. _printTemplate.graphics.drawRect(0, 0, _printA4width, _printA4height);
  151. _printTemplate.graphics.endFill();
  152.  
  153. }
  154.  
  155.  
  156. private function createControls():void
  157. {
  158. _controls = new Sprite();
  159.  
  160. var bg:Shape = new Shape();
  161. bg.graphics.beginFill(0x000000, 0.1);
  162. bg.graphics.drawRect(0, 0, stage.stageWidth, _controlsHeight);
  163. bg.graphics.endFill();
  164. _controls.addChild(bg);
  165.  
  166. var title:Bitmap = new TitleGraphic();
  167. title.x = 10;
  168. title.y = 10;
  169. _controls.addChild(title);
  170.  
  171. var urlLabel:Label = new Label(_controls, 13, 29, "Message/URL");
  172.  
  173. _urlText = new Text(_controls, 80, 28, "");
  174. _urlText.addEventListener(Event.CHANGE, onUrlText_CHANGE);
  175. _urlText.textField.multiline = false;
  176. _urlText.width = 375;
  177. _urlText.height = 20;
  178.  
  179. _dimensionsSlider = new HUISlider(_controls, 10, 50, "Size (in pixels)", onDimensionsSlider);
  180. _dimensionsSlider.width = 500;
  181. _dimensionsSlider.minimum = 50;
  182. _dimensionsSlider.maximum = stage.stageHeight - _controlsHeight;
  183. _dimensionsSlider.value = _defaultSize;
  184. _dimensionsSlider.labelPrecision = 0;
  185.  
  186. _generateBtn = new PushButton(_controls, 80, 69, "Generate", onGenerateBtn);
  187. _generateBtn.width = 71;
  188. _generateBtn.enabled = false;
  189.  
  190. _savePngBtn = new PushButton(_controls, 156, 69, "Save as PNG", onSavePngBtn);
  191. _savePngBtn.width = 71;
  192. _savePngBtn.enabled = false;
  193.  
  194. _saveJpegBtn = new PushButton(_controls, 232, 69, "Save as JPEG", onSaveJpegBtn);
  195. _saveJpegBtn.width = 71;
  196. _saveJpegBtn.enabled = false;
  197.  
  198. _printBtn = new PushButton(_controls, 308, 69, "Print A4", onPrintBtn);
  199. _printBtn.width = 71;
  200. _printBtn.enabled = false;
  201.  
  202. _pdfBtn = new PushButton(_controls, 384, 69, "Create PDF", onPdfBtn);
  203. _pdfBtn.width = 71;
  204. _pdfBtn.enabled = false;
  205.  
  206. addChild(_controls);
  207. }
  208.  
  209.  
  210. private function onDimensionsSlider(event:Event):void
  211. {
  212. if (_url.length > 0) {
  213. _generateBtn.enabled = true;
  214. } else {
  215. _generateBtn.enabled = false;
  216. }
  217. _savePngBtn.enabled = false;
  218. _saveJpegBtn.enabled = false;
  219. _printBtn.enabled = false;
  220. _pdfBtn.enabled = false;
  221. _qrLoader.visible = false;
  222. }
  223.  
  224.  
  225. private function onUrlText_CHANGE(event:Event):void
  226. {
  227. //trace("onUrlText()");
  228. _url = _urlText.text;
  229. //trace("_url:", _url);
  230. if (_url.length > 0) {
  231. _generateBtn.enabled = true;
  232. } else {
  233. _generateBtn.enabled = false;
  234. }
  235. _savePngBtn.enabled = false;
  236. _saveJpegBtn.enabled = false;
  237. _printBtn.enabled = false;
  238. _pdfBtn.enabled = false;
  239. _qrLoader.visible = false;
  240. }
  241.  
  242.  
  243. private function onGenerateBtn(event:Event):void
  244. {
  245. trace("onGenerateBtn()");
  246.  
  247. _generateBtn.enabled = false;
  248.  
  249. _qrLoader.visible = false;
  250. _loadingAnim.visible = true;
  251.  
  252. _url = _urlText.text;
  253. _size = _dimensionsSlider.value;
  254.  
  255. _errorTxt.visible = false;
  256.  
  257. _urlVars = new URLVariables();
  258. _urlRequest = new URLRequest();
  259.  
  260. _urlVars.chs = String(_size + "x" + _size);
  261.  
  262. if (Security.sandboxType == Security.LOCAL_TRUSTED) {
  263. // If 'LOCAL_TRUSTED' then load the image from Google directly.
  264. trace("Security.sandboxType == Security.LOCAL_TRUSTED");
  265. _urlVars.cht = "qr";
  266. _urlVars.chl = _url;
  267. _urlRequest.url = _googleUrl;
  268. } else {
  269. // Else, circumvent using a server-side proxy script
  270. trace("Security.sandboxType != Security.LOCAL_TRUSTED");
  271. _urlVars.chl = encodeURIComponent(_url);
  272. _urlVars.googleUrl = _googleUrl;
  273. _urlRequest.url = _serversideProxyUrl;
  274. }
  275.  
  276. _urlRequest.data = _urlVars;
  277.  
  278. trace("vars.toString():" + _urlVars.toString());
  279. trace("_urlRequest: ", _urlRequest.url);
  280.  
  281. _savePngBtn.enabled = false;
  282. _saveJpegBtn.enabled = false;
  283. _printBtn.enabled = false;
  284. _pdfBtn.enabled = false;
  285.  
  286. var loaderContext:LoaderContext = new LoaderContext ();
  287. loaderContext.checkPolicyFile = true;
  288.  
  289. _qrLoader.load(_urlRequest, loaderContext);
  290. }
  291.  
  292.  
  293. private function onSavePngBtn(event:Event):void
  294. {
  295. trace("onSavePngBtn()");
  296.  
  297. var qrCodeBitmap:Bitmap = Bitmap(_qrLoader.content);
  298. _qrCodeBitmapData = qrCodeBitmap.bitmapData;
  299.  
  300. //var pngEncoder:PNGEncoder = new PNGEncoder(90);
  301. var imageByteArray:ByteArray = PNGEncoder.encode(_qrCodeBitmapData);
  302.  
  303. var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
  304. var pngURLRequest:URLRequest = new URLRequest(_createPngFilePhpUrl+"?name="+_imageFilename+".png");
  305. pngURLRequest.requestHeaders.push(header);
  306. pngURLRequest.method = URLRequestMethod.POST;
  307. pngURLRequest.data = imageByteArray;
  308. navigateToURL(pngURLRequest, "_blank");
  309. }
  310.  
  311.  
  312. private function onSaveJpegBtn(event:Event):void
  313. {
  314. trace("onSaveJpegBtn()");
  315. //navigateToURL(_urlRequest, "_blank");
  316.  
  317. var qrCodeBitmap:Bitmap = Bitmap(_qrLoader.content);
  318. _qrCodeBitmapData = qrCodeBitmap.bitmapData;
  319.  
  320. var jpgEncoder:JPGEncoder = new JPGEncoder(90);
  321. var imageByteArray:ByteArray = jpgEncoder.encode(_qrCodeBitmapData);
  322.  
  323. var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
  324. var jpgURLRequest:URLRequest = new URLRequest(_createJpegFilePhpUrl+"?name="+_imageFilename+".jpg");
  325. jpgURLRequest.requestHeaders.push(header);
  326. jpgURLRequest.method = URLRequestMethod.POST;
  327. jpgURLRequest.data = imageByteArray;
  328. navigateToURL(jpgURLRequest, "_blank");
  329. }
  330.  
  331.  
  332. private function onPrintBtn(event:Event):void
  333. {
  334. trace("onPrintBtn()");
  335. var pj:PrintJob = new PrintJob();
  336.  
  337. if (pj.start()) {
  338. try {
  339. var tempBitmapData:BitmapData = new BitmapData( _size, _size);
  340. tempBitmapData.draw(_qrLoader);
  341. var qrCodeBitmap:Bitmap = new Bitmap(tempBitmapData);
  342.  
  343. var qrCodeSprite:Sprite = new Sprite();
  344. qrCodeSprite.addChild(qrCodeBitmap);
  345.  
  346. var scale:Number = _printTemplate.width / _size;
  347. qrCodeSprite.scaleX = qrCodeSprite.scaleY = scale;
  348.  
  349. qrCodeSprite.y = (_printTemplate.height / 2) - (qrCodeSprite.height / 2);
  350. _printTemplate.addChild(qrCodeSprite);
  351.  
  352. pj.addPage(_printTemplate);
  353. }
  354. catch(error:Error) {
  355. trace("There was an error with the PrintJob");
  356. }
  357. pj.send();
  358. } else {
  359. trace("PrintJob was cancelled");
  360. }
  361.  
  362. }
  363.  
  364.  
  365. private function onPdfBtn(event:Event):void
  366. {
  367. trace("onPdfBtn()");
  368.  
  369. var myPDF:PDF = new PDF(Orientation.PORTRAIT, Unit.MM, Size.A4);
  370. myPDF.setDisplayMode(Display.FULL_WIDTH);
  371.  
  372. myPDF.addPage();
  373.  
  374. var pdfSheet:Sprite = new Sprite();
  375. pdfSheet.graphics.beginFill(0xFFFFFF, 1);
  376. pdfSheet.graphics.drawRect(0, 0, _pdfA4width, _pdfA4height);
  377. pdfSheet.graphics.endFill();
  378.  
  379. var tempBitmapData:BitmapData = new BitmapData( _size, _size);
  380. tempBitmapData.draw(_qrLoader);
  381. var qrCodeBitmap:Bitmap = new Bitmap(tempBitmapData);
  382. var qrCodeSprite:Sprite = new Sprite();
  383. qrCodeSprite.addChild(qrCodeBitmap);
  384. var scale:Number = pdfSheet.width / _size;
  385. qrCodeSprite.scaleX = qrCodeSprite.scaleY = scale;
  386. qrCodeSprite.y = (pdfSheet.height / 2) - (qrCodeSprite.height / 2);
  387. pdfSheet.addChild(qrCodeSprite);
  388.  
  389. myPDF.addImage(pdfSheet);
  390.  
  391. var fileReference:FileReference = new FileReference();
  392. var byteArray:ByteArray = myPDF.save(Method.LOCAL);
  393. fileReference.save(byteArray, _pdfFilename);
  394. fileReference.addEventListener(IOErrorEvent.IO_ERROR, onFileReference_IO_ERROR);
  395. }
  396.  
  397.  
  398. private function onFileReference_IO_ERROR(event:IOErrorEvent):void
  399. {
  400. trace("onFileReference_IO_ERROR()");
  401.  
  402. }
  403.  
  404.  
  405. private function onQrLoader_COMPLETE(event:Event):void {
  406. _loadingAnim.visible = false;
  407.  
  408. _qrLoader.x = stage.stageWidth / 2 - _qrLoader.width / 2;
  409. _qrLoader.y = ((stage.stageHeight-_controlsHeight) / 2) - (_qrLoader.height / 2) + _controlsHeight;
  410. _qrLoader.visible = true;
  411.  
  412. addChild(_qrLoader);
  413. addChild(_border);
  414.  
  415. _savePngBtn.enabled = true;
  416. _saveJpegBtn.enabled = true;
  417. _printBtn.enabled = true;
  418. _pdfBtn.enabled = true;
  419.  
  420. // NOTE: This will fail online because Google Charts
  421. // doesn't have a crossdomain.xml file.
  422. // To get around this issue we are using a serverside proxy script using PHP.
  423. var bmp:Bitmap = _qrLoader.content as Bitmap ;
  424. bmp.smoothing = true ;
  425. }
  426.  
  427.  
  428. private function onQrLoader_IO_ERROR(event:IOErrorEvent):void
  429. {
  430. trace("onQrLoader_IO_ERROR()");
  431. trace("event: " + event);
  432. _loadingAnim.visible = false;
  433. var errorMsg:String = "The was an error loading the following url:\n" + _urlRequest.url + "?" + _urlVars.toString();
  434. displayTextInMiddleOfScreen(errorMsg);
  435. }
  436.  
  437.  
  438. private function onQrLoader_HTTP_STATUS(event:HTTPStatusEvent):void
  439. {
  440.  
  441. trace("onQrLoader_HTTP_STATUS()");
  442. trace("event: " + event);
  443. trace("event.status: " + event.status);
  444. }
  445.  
  446.  
  447. private function drawBorder($borderColour:uint = 0x0000, $borderWidth:uint = 1, $borderAlpha:Number = 1):Shape
  448. {
  449. var border:Shape = new Shape();
  450.  
  451. border.graphics.beginFill($borderColour, $borderAlpha);
  452. border.graphics.drawRect($borderWidth, 0, stage.stageWidth-$borderWidth, $borderWidth);
  453. border.graphics.endFill();
  454.  
  455. border.graphics.beginFill($borderColour, $borderAlpha);
  456. border.graphics.drawRect(stage.stageWidth-$borderWidth, $borderWidth, $borderWidth, stage.stageHeight-$borderWidth);
  457. border.graphics.endFill();
  458.  
  459. border.graphics.beginFill($borderColour, $borderAlpha);
  460. border.graphics.drawRect(0, stage.stageHeight-$borderWidth, stage.stageWidth-$borderWidth, $borderWidth);
  461. border.graphics.endFill();
  462.  
  463. border.graphics.beginFill($borderColour, $borderAlpha);
  464. border.graphics.drawRect(0, 0, $borderWidth, stage.stageHeight-$borderWidth);
  465. border.graphics.endFill();
  466.  
  467. return border;
  468. }
  469.  
  470.  
  471. private function displayTextInMiddleOfScreen($msg:String):void
  472. {
  473. var tf:TextFormat = new TextFormat();
  474. tf.align = TextFormatAlign.CENTER;
  475. tf.size = 10;
  476. tf.bold = true;
  477. tf.font = "_sans";
  478. tf.color = 0x666666;
  479.  
  480. _errorTxt.text = $msg;
  481. _errorTxt.border = true;
  482. _errorTxt.width = 400;
  483. _errorTxt.wordWrap = true;
  484. _errorTxt.autoSize = TextFieldAutoSize.CENTER;
  485.  
  486. _errorTxt.setTextFormat(tf);
  487. _errorTxt.x = (stage.stageWidth / 2) - (_errorTxt.width / 2);
  488. _errorTxt.y = ((stage.stageHeight-_controlsHeight) / 2) - (_errorTxt.height / 2) + _controlsHeight - 10;
  489.  
  490. _errorTxt.visible = true;
  491. addChild(_errorTxt);
  492. }
  493.  
  494. }
  495.  
  496. }

URL: http://www.adrianparr.com/?p=140

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.