1. 程式人生 > >as3+php上傳圖片的三種方式

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 的路徑

image

image

2、因為在flashDevelop中使用到了fl元件,所以需要先下載fl.swc,可以在google code上下載的到,

下載連結地址>>  (關於在flashdevelop中如何使用swc,可以gg一下)

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~~~";
?>

執行後,可以在相應的目錄中看到圖片已經上傳成功了,如下圖所示:

image

image

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!!";
?>

image

控制檯上可以看到將bitmapdata轉為字串的結果:

image

後臺儲存得到的圖片:

image

三、使用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;
  
?>

程式執行後的效果(對預覽圖片進行了等比壓縮處理,可以在列出的圖中看出原圖很大):

image

image

image

以上三種方式,在不同的場景下面可能應用不太一樣,比如第二種,使用編碼後的字串方式進行傳輸的,這樣就可以通過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或是其它…