as3+php上傳圖片的三種方式
這裡的三種方式分別為:
1、二進位制傳輸(BINARY)
2、字串傳輸(String)
3、檔案流上傳(File)
開發IDE:FlashDevelop、Zend Studio。
1)設定FlashDevelop使用flash player10(debug版本,因為有一個demo使用了本地預覽)
“工具”選單 –》 “軟體設定”(快捷鍵F10)—》 點選左側的“AS3Context”,在Language中的“Default Flash Version”修改為10,選擇Player Debug 的路徑
2、因為在flashDevelop中使用到了fl元件,所以需要先下載fl.swc,可以在google code上下載的到,
3、使用到了Adobe的官方元件PNGEncoder,google code上的下載地址>>
一、使用二進位制上傳圖片
完整的as3程式碼:
package { import com.adobe.images.JPGEncoder; import com.adobe.images.PNGEncoder; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.display.MovieClip; import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import fl.controls.Button; import flash.events.MouseEvent; import flash.filters.GlowFilter; import flash.net.*; import flash.filters.BitmapFilterQuality; import flash.utils.ByteArray; /** * ... * @author ZhangYi */ public class Main extends Sprite { private var _base:Shape; private var _btn:Button; private var _loader:Loader; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point inited(); } private function inited():void { var mc:MovieClip = new MovieClip(); mc.graphics.beginFill(0x000000, 0.2); mc.graphics.drawRect(0, 0, 320, 455); mc.x = 30; mc.y = 60; addChild(mc); _loader = new Loader(); _loader.load(new URLRequest("../assets/1.png")); mc.addChild(_loader); _loader.addEventListener(MouseEvent.ROLL_OVER, addFilterHandler); _loader.addEventListener(MouseEvent.ROLL_OUT, removeFilterHandler); _btn = new Button(); _btn.label = "截圖"; _btn.x = 30; _btn.y = 30; addChild(_btn); _btn.addEventListener(MouseEvent.CLICK, clickHandler); } private function clickHandler(evt:MouseEvent):void { var bitmapData:BitmapData = new BitmapData(_loader.width, _loader.height, true, 0); bitmapData.draw(_loader); //var encoder:JPGEncoder = new JPGEncoder(100); //var bytes:ByteArray = encoder.encode(bitmapData); var bytes:ByteArray = PNGEncoder.encode(bitmapData); var req:URLRequest = new URLRequest("http://meteoric.com/test/uploadFile/upload_1.php"); req.data = bytes; req.method = URLRequestMethod.POST; req.contentType = "application/octet-stream"; var loader:URLLoader = new URLLoader(); loader.dataFormat = URLLoaderDataFormat.BINARY; loader.load(req); loader.addEventListener(Event.COMPLETE, completeHandler); } private function completeHandler(evt:Event):void { trace(evt.target.data); } private function addFilterHandler(evt:MouseEvent):void { var filtersArr:Array = new Array(); filtersArr = _loader.filters; filtersArr.push(getBitmapFilter()); _loader.filters = filtersArr; } private function removeFilterHandler(evt:MouseEvent):void { _loader.filters = null; } private function getBitmapFilter():GlowFilter { var color:Number = 0xFF0000; var alpha:Number = 1; var blurX:Number = 5; var blurY:Number = 5; var strength:Number = 4; var inner:Boolean = false; var knockout:Boolean = false; var quality:Number = BitmapFilterQuality.LOW; return new GlowFilter(color, alpha, blurX, blurY, strength, quality, inner, knockout); } } }
後臺php的程式碼:
<?php $filename="teststream.jpg";//要生成的圖片名字 $xmlstr = $GLOBALS[HTTP_RAW_POST_DATA]; if(empty($xmlstr)) { $xmlstr = file_get_contents('php://input'); } $jpg = $xmlstr;//得到post過來的二進位制原始資料 $file = fopen("image/".$filename,"w");//開啟檔案準備寫入 fwrite($file,$jpg);//寫入 fclose($file);//關閉 echo "ok~~~"; ?>
執行後,可以在相應的目錄中看到圖片已經上傳成功了,如下圖所示:
PHP預設只識別application/x-www.form-urlencoded標準的資料型別。
因此,對型如text/xml 或者 soap 或者 application/octet-stream 之類的內容無法解析,如果用$_POST陣列來接收就會失敗! 故保留原型,交給$GLOBALS['HTTP_RAW_POST_DATA'] 來接收。
另外還有一項 php://input 也可以實現此這個功能
php://input 允許讀取 POST 的原始資料。和 $HTTP_RAW_POST_DATA 比起來,它給記憶體帶來的壓力較小,並且不需要任何特殊的 php.ini 設定。php://input和 $HTTP_RAW_POST_DATA 不能用於 enctype=”multipart/form-data”。’
而在前臺則使用JPGEncoder或是PNGEncoder將BitmapData轉成二進位制,使用post傳給php
二、使用字串提交(採用Base64編碼)
as3程式碼:
package { import com.adobe.images.JPGEncoder; import com.adobe.images.PNGEncoder; import com.hurlant.util.Base64; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.display.MovieClip; import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import fl.controls.Button; import flash.events.MouseEvent; import flash.filters.GlowFilter; import flash.net.*; import flash.filters.BitmapFilterQuality; import flash.utils.ByteArray; /** * ... * @author ZhangYi */ public class Base64Test extends Sprite { private var _base:Shape; private var _btn:Button; private var _loader:Loader; public function Base64Test() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point inited(); } private function inited():void { var mc:MovieClip = new MovieClip(); mc.graphics.beginFill(0x000000, 0.2); mc.graphics.drawRect(0, 0, 320, 455); mc.x = 30; mc.y = 60; addChild(mc); _loader = new Loader(); _loader.load(new URLRequest("../assets/1.png")); mc.addChild(_loader); _loader.addEventListener(MouseEvent.ROLL_OVER, addFilterHandler); _loader.addEventListener(MouseEvent.ROLL_OUT, removeFilterHandler); _btn = new Button(); _btn.label = "截圖"; _btn.x = 30; _btn.y = 30; addChild(_btn); _btn.addEventListener(MouseEvent.CLICK, clickHandler); } private function clickHandler(evt:MouseEvent):void { addFilterHandler(); var bitmapData:BitmapData = new BitmapData(_loader.width, _loader.height, true, 0); bitmapData.draw(_loader); var bytes:ByteArray = PNGEncoder.encode(bitmapData); var pngString:String = Base64.encodeByteArray(bytes); var variables:URLVariables = new URLVariables(); variables.png = pngString; variables.name = "photo002"; var req:URLRequest = new URLRequest("http://meteoric.com/test/uploadFile/upload_2.php"); req.data = variables; req.method = URLRequestMethod.POST; var urlloader:URLLoader = new URLLoader(); urlloader.dataFormat = URLLoaderDataFormat.VARIABLES; urlloader.addEventListener(Event.COMPLETE, completeHandler); urlloader.load(req); trace(pngString); } private function completeHandler(evt:Event):void { trace(evt.target.data); } private function addFilterHandler(evt:MouseEvent=null):void { var filtersArr:Array = new Array(); filtersArr = _loader.filters; filtersArr.push(getBitmapFilter()); _loader.filters = filtersArr; } private function removeFilterHandler(evt:MouseEvent):void { _loader.filters = null; } private function getBitmapFilter():GlowFilter { var color:Number = 0xFF0000; var alpha:Number = 1; var blurX:Number = 5; var blurY:Number = 5; var strength:Number = 4; var inner:Boolean = false; var knockout:Boolean = false; var quality:Number = BitmapFilterQuality.LOW; return new GlowFilter(color, alpha, blurX, blurY, strength, quality, inner, knockout); } } }
後臺php程式碼:
<?php function base64_to_png($inputfile, $outputfile ) { $imageData = $inputfile; $file = fopen( $outputfile, "w" ); fwrite( $file, base64_decode( $imageData ) ); fclose($file); } base64_to_png("".$_POST['png'], "image/". $_POST["name"] . ".png"); print "info=ok!!"; ?>
控制檯上可以看到將bitmapdata轉為字串的結果:
後臺儲存得到的圖片:
三、使用FileReference類進行上傳
as3程式碼:
package { import fl.controls.Button; import flash.display.Loader; import flash.display.Sprite; import flash.events.DataEvent; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.BevelFilter; import flash.net.FileFilter; import flash.net.FileReference; import flash.net.URLRequest; import flash.utils.ByteArray; /** * ... * @author ZhangYi */ public class FileReferenceUpload extends Sprite { private var _btn:Button; private var _fileRef:FileReference; private var _loader:Loader; public function FileReferenceUpload() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point inited(); } private function inited():void { _btn = new Button(); _btn.label = "選擇圖片"; _btn.x = 100; _btn.y = 100; addChild(_btn); _btn.addEventListener(MouseEvent.CLICK, clickHandler); _loader = new Loader(); _loader.x = 100; _loader.y = 150; addChild(_loader); _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, resizeImage); } private function resizeImage(evt:Event):void { var size:uint = 300; var w:Number = _loader.width; var h:Number = _loader.height; var scale:Number = w / h; if (w > h) { _loader.width = size; _loader.height = size / scale; } else if (h > w) { _loader.height = size; _loader.width = size * scale; } else { _loader.height = _loader.width = size; } var req:URLRequest = new URLRequest("http://meteoric.com/test/uploadFile/upload_3.php"); _fileRef.upload(req); } private function getImageFilter():FileFilter { return new FileFilter("支援的圖片型別(*.jpg;*.jpeg;*.gif;*.png)", "*.jpg;*.jpeg;*.gif;*.png"); } private function getFilterTypes():Array { return [ getImageFilter(), new FileFilter("GIF 檔案 (*.gif)", "*.gif"), new FileFilter("PNG 檔案 (*.png)", "*.png"), new FileFilter("JPG 檔案 (*.jpg)", "*.jpg;*.jpeg") ]; } private function clickHandler(evt:MouseEvent):void { _fileRef = null; _fileRef = new FileReference(); _fileRef.addEventListener(Event.SELECT, selectHandler, false, 0, true); _fileRef.addEventListener(Event.COMPLETE, onloadedHandler, false, 0, true); _fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadImageCompleteHandler, false, 0, true); _fileRef.browse(getFilterTypes()); } private function selectHandler(evt:Event):void { _fileRef.removeEventListener(Event.SELECT, selectHandler); _fileRef.load(); } private function onloadedHandler(evt:Event):void { _fileRef.removeEventListener(Event.COMPLETE, onloadedHandler); _loader.loadBytes(_fileRef.data); } private function uploadImageCompleteHandler(evt:DataEvent):void { trace(evt.data); _fileRef.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadImageCompleteHandler); _fileRef = null; } } }
後臺php程式碼:
<?php if ($_FILES ["Filedata"] ["error"] > 0) { exit("Error: " . $_FILES ["Filedata"]["error"]); } $fileName = iconv("utf-8","gb2312", $_FILES ["Filedata"]["name"]); $reallyName = "image/".$fileName; if (file_exists ($reallyName)) { unlink($reallyName); } if (!is_dir("upload")) { mkdir("upload"); } move_uploaded_file( $_FILES ["Filedata"]["tmp_name"], $reallyName); echo "Stored in: " . "image/" . $fileName; ?>
程式執行後的效果(對預覽圖片進行了等比壓縮處理,可以在列出的圖中看出原圖很大):
以上三種方式,在不同的場景下面可能應用不太一樣,比如第二種,使用編碼後的字串方式進行傳輸的,這樣就可以通過socket通道傳輸資料了(雖然這很浪費而且耗費頻寬,環境允許的話還是應該優先考慮使用web介面進行處理)。針對不同的上傳方式,後臺處理各不一樣,可以看到上面的三個php寫的都不一樣。
用到的類也比較簡單(ImageSnapshot中的encodeImageAsBase64、captureImage):
private function getBase64StringFromBody():String { var _matrix:Matrix = new Matrix(1,0,0,1,0,0); _matrix.scale(1,1); var bitmapData:BitmapData = new BitmapData(320,455,true,0); bitmapData.draw(photoEditContainer, _matrix); var bt:Bitmap = new Bitmap(bitmapData,"auto",true); var tempCan:Canvas = new Canvas(); tempCan.rawChildren.addChild(bt); _matrix = new Matrix(1,0,0,1,0,0); bitmapData = new BitmapData(320,455,true,0); bitmapData.draw(tempCan,_matrix); var codeStr:String = ImageSnapshot.encodeImageAsBase64( ImageSnapshot.captureImage( bitmapData ) ); tempCan.rawChildren.removeChild(bt); bitmapData.dispose(); bitmapData = null return codeStr; }
提供本文中所有as3的原始碼下載,後臺可以用自己熟悉的任何一門語言寫寫就好:java、.net、python或是其它…