关于Flex拍照的文章很多,Camera的用法基本上类似。
上传的一般做法是:得到ByteArray之后直接放在Request的体内容中传给服务器端,服务器打开请求流,直接读取byte[]数组。
但对于我的应用,该方法存在如下几点不足:1)由于服务器是自己写的IOCP服务器,内置了文件上传组件,如果直接解析的话,就要重新编写组件;2)直接读取对于大照片(可能超过10MB)上传性能不利;3)无法同时传输多个照片或文件;4)无法同时传输文本型变量(特别是多行文本)。
因此,决定在ByteArray的基础上重新封装客户端URLRequest的体内容,兼容multipart/form-data类型。
第一步:实现拍照并得到ByteArray数据。
var camera:Camera;
var video:Video = null;
private function videoDisplay_creationComplete():void {
camera = Camera.getCamera();
if(camera){
//指定是否播放来自摄像头的视频流。
camera.setMode(videoDisplay.width, videoDisplay.height, 20); //180, 240, 20);
video = new Video(camera.width, camera.height);
video.attachCamera(camera);
videoDisplay.addChild(video);
}else{
Alert.show("You don't seem to have a camera.");
}
}
var imageBytes:ByteArray = null;
var photoFilename:String = "photo.jpg";
private function cut_pic():void{
var imgBD:BitmapData = new BitmapData(camera.width, camera.height);
imgBD.draw(videoDisplay, new Matrix());
var imgBitmap:Bitmap = new Bitmap(imgBD);
//创建一个UIComponent对象
var uic:UIComponent = new UIComponent();
//将Bitmap对象加入到UIComponent对象中
uic.addChild(imgBitmap);
showimg.addChild(uic);
var encoder :JPEGEncoder = new JPEGEncoder(100);
imageBytes = encoder.encode(imgBD);
uploadButton.enabled = true;
}
这一步代码网络上都能找到。
第二步:封装为multipart/form-dada并上传。
private function upload_clickHandler(event:MouseEvent):void
{
var bound:String = "---------------------------293342587424372"; //暂时固定,留待扩充
var cntType: String = "multipart/form-data;boundary=" + bound;
var header:URLRequestHeader = new URLRequestHeader ("Content-Type", cntType);
var urlstr:String = "/index?opr=MyPhoto&sopr=Upload";
var request:URLRequest = new URLRequest(urlstr);
request.requestHeaders.push(header);
request.method = "POST";
var data:ByteArray = new ByteArray(); //用于保存URLRequest体内容的数组
//开始封装一个文件(图片)
var ts:String = "--" + bound + "\r\n" + "Content-Disposition: form-data; name=\"photo\"; filename=\"" + photoFilename + "\"\r\n";
ts += "Content-Type: image/jpg\r\n\r\n";
data.writeMultiByte(ts, "GB2312");
data.position = data.length;
data.writeBytes(imageBytes);
//封装文件结束(如果含有多个文件,可以重复上述这一小段代码)
//添加结束分隔符
var es:String = "\r\n--" + bound + "--\r\n";
data.position = data.length;
data.writeMultiByte(es, "GB2312");
request.data = data; //添加为URLRequest的体内容
var load:URLLoader = new URLLoader(request);
load.addEventListener(Event.COMPLETE, function(evt){Alert.show(load.data);});
}
至此,上传部分代码结束,之后就是服务器端文件上传组件接收数据的代码(略)。