Flash实现图片上传(实现浏览器端图片预览)

由于项目需要,在客户上传搭配的过程中要实现图片在浏览器预览的功能,实在是纠结。思考过,个人认为要实现图片的本地预览可以通过编写ActiveX控件或者使用Flash做到。当然编写ActiveX控件会在浏览器端出现控件安装的过程,十分不友好,况且很多浏览器认为ActiveX控件是不安全的会屏蔽,只能抛弃。本以为Flash实现会很容易,可是到做的时候才发现,Flash 10在真正支持图片的本地预览(FileReference),当然产品的需求还有些变态的,需要实现AS与JS的互调。贴出代码,并对关键点加以说明。

View Code
package
{
import com.yahoo.astra.fl.charts.axes.IClusteringAxis;
import fl.events.InteractionInputType;
import flash.display.
*;
import flash.geom.Rectangle;
import flash.net.
*;
import flash.text.
*;
import flash.filters.
*;
import flash.events.
*;
import flash.system.Security;
import flash.external.ExternalInterface;

import fl.controls.Button;
import fl.controls.ProgressBar;
import fl.controls.ProgressBarMode;

/**
* ...
* @author Olar Tan
*/
public class Main extends Sprite
{
//fontColor=#ff4570;
//bgColor=#1a1a1a;
private const DEFAULT_UPLOAD_PAGE:String = "http://www.xxx.com/upload.aspx";
private const BOX_WIDTH:uint
= 400;
private const BOX_HEIGHT:uint
= 600;

private const STATE_CACHE:String
= "cache";
private const STATE_UPLOAD:String
= "upload";

[Embed(source
= '../lib/bg.png')]
private
var Pic:Class; //;

private
var _filters:Array;
private
var _file:FileReference;
private
var _loader:Loader;
private
var _progress:ProgressBar;
private
var _state:String;
private
var _buttons:Array;
private
var _labels:Array;
private
var _txts:Array;
private
var _rect:Rectangle;
private
var _state_txt:TextField;
private
var _lblChoose:TextField;

private
var _upload_url:String;
private
var _contactId:String;
private
var _isPkFlag:String;
private
var _pkId:String;
private
var _upload_complete_callback:String;

private
var _pic:* = new Pic();

public
function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private
function init(e:Event = null):void
{

_upload_url
= stage.loaderInfo.parameters["uploadURL"];
_contactId
= stage.loaderInfo.parameters["contactId"];
_pkId
= stage.loaderInfo.parameters["pkId"];
_isPkFlag
= stage.loaderInfo.parameters["isPkFlag"];
_upload_complete_callback
= stage.loaderInfo.parameters["uploadCompleteCallback"];


ExternalInterface.addCallback(stage.loaderInfo.parameters[
"outerUploadPhotoCallback"], outerEventUploadPhoto);
ExternalInterface.addCallback(stage.loaderInfo.parameters[
"outerChoosePhotoCallback"],outerEventChoosePhoto);
removeEventListener(Event.ADDED_TO_STAGE, init);
Security.allowDomain(
"*");

_buttons
= [];
_txts
= [];
_labels
= ["文件名称:","文件类型:","文件大小:","修改时间:"];

_rect
= new Rectangle(0, 30, 400, 600);
_state
= STATE_CACHE;
this.addChild(_pic);


//背景;
this.graphics.beginFill(0xffffff);
this.graphics.drawRect(0, 0, 400, 30);
this.graphics.endFill();

//标题;
var label:TextField;
label
= getLabel("搭配照片:", getTextFormat(0x333333, 14, false));
label.x
= 0;
label.y
= 5;
this.addChild(label);

//重新选择按钮
_lblChoose = getLabel("重新选择照片", getTextFormat(0xff4570, 14, true, true), true);
_lblChoose.x
= 90;
_lblChoose.y
= 5;
_lblChoose.addEventListener(MouseEvent.CLICK, clickHandler);
this.addChild(_lblChoose);
_lblChoose.visible
= false;

for (var i:uint = 0; i < _labels.length; i++ ) {
label
= getLabel(_labels[i], getTextFormat(0x333333, 12), false, false);
label.x
= _rect.right+5;
label.y
= _rect.y + 25 * i;
label.width
= 280;
label.height
= 20;
_txts.push(label);
//this.addChild(label);
}

//状态
_state_txt = getLabel("状态:", getTextFormat(0x333333, 12));
_state_txt.x
= 170;
_state_txt.y
= 5;
//this.addChild(_state_txt);

//按钮选择
var button:Button;
button
= getButton("选择文件", 130);
button.move(
135, 220);

//按钮上传
button = getButton("上传文件", 80);
button.move(
300, 5);
button.enabled
= false;
button.visible
= false;

//进度条;
_progress = new ProgressBar();
_progress.move(
20, 80);
_progress.setSize(
290,22);
_progress.mode
= ProgressBarMode.MANUAL;
//this.addChild(_progress);

//文件类型;
_filters = [];
var filter:FileFilter;
filter
= new FileFilter("所有支持图片文件(*.jpg,*.jpeg,*.gif,*.png)", "*.jpg;*.jpeg;*.gif;*.png");
_filters[_filters.length]
= filter;
filter
= new FileFilter("JPEG files(*.jpg,*.jpeg)","*.jpg;*.jpeg");
_filters[_filters.length]
= filter;
filter
= new FileFilter("GIF files (*.gif)","*.gif");
_filters[_filters.length]
= filter;
filter
= new FileFilter("PNG files(*.png)","*.png");
_filters[_filters.length]
= filter;

_file
= new FileReference();
_file.addEventListener(Event.COMPLETE, fileHandler);
_file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, fileHandler);
_file.addEventListener(Event.SELECT, fileHandler);
_file.addEventListener(Event.OPEN, fileHandler);
_file.addEventListener(ProgressEvent.PROGRESS, fileHandler);
_file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, fileHandler);
_file.addEventListener(IOErrorEvent.IO_ERROR, fileHandler);
_file.addEventListener(HTTPStatusEvent.HTTP_STATUS, fileHandler);

_loader
= new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadHandler);
this.addChild(_loader);



}

public
function get state():String {
return _state;
}

private
function clickHandler(event:MouseEvent):void {
switch(event.target) {
case _lblChoose:
case _buttons[0]:
_file.browse(_filters);
break;
case _buttons[1]:
var urlRequest:URLRequest = new URLRequest(_upload_url);
_file.upload(urlRequest);
_state
= STATE_UPLOAD;
_buttons[
0].enabled = false;
_buttons[
1].enabled = false;
break;
}
}

private
function outerEventUploadPhoto(mediaStyle:int,mediaDesc:String):void {
try
{
var urlRequest:URLRequest = new URLRequest(_upload_url+"?contactId="+_contactId+"&pkId="+_pkId+"&isPkFlag="+_isPkFlag+"&mediaStyle="+mediaStyle+"&mediaDesc="+mediaDesc);
_file.upload(urlRequest);
_state
= STATE_UPLOAD;
}
catch(e:Error){}

}

private
function outerEventChoosePhoto():void {
debug(
"选择图片.");
}

private
function loadHandler(event:Event):void {

_buttons[
0].visible = false;
_lblChoose.visible
= true;

_loader.scaleX
= _loader.scaleY = 1;
var w:uint = _loader.width;
var h:uint = _loader.height;
if (w > _rect.width || h > _rect.height) {
var ip:Number = w / h;
var lp:Number = _rect.width / _rect.height;
_loader.width
= (ip > lp)?_rect.width:_rect.height*ip;
_loader.height
= (ip > lp)?_rect.width / ip:_rect.height;
}
_loader.x
= _rect.x + (_rect.width - _loader.width) / 2;
_loader.y
= _rect.y + (_rect.height - _loader.height) / 2;

_loader.visible
= true;

}

private
function fileHandler(event:Event):void {
var result:String = '';
switch(event.type) {
case Event.COMPLETE:
if(state == STATE_CACHE){
_loader.loadBytes(_file.data);
}
break;
case DataEvent.UPLOAD_COMPLETE_DATA:
debug(
"图片上传完成!");
_buttons[
0].enabled = true;
_buttons[
1].enabled = false;
_progress.setProgress(
0, 1);
var dEvent:DataEvent = event as DataEvent;
result
= dEvent.data.toString();
break;
case Event.SELECT:
_txts[
0].text = _labels[0] + _file.name;
_txts[
1].text = _labels[1] + _file.type;
_txts[
2].text = _labels[2] + ((_file.size > 1024 * 1024)?Math.round(_file.size * 10 / (1024*1024))/10
+ "MB":Math.round(_file.size * 10 / 1024)/10 + "KB");
_txts[3].text = _labels[3] + date2str(_file.modificationDate);
_buttons[
0].enabled = true;
_buttons[
1].enabled = true;
_file.load();
_state
= STATE_CACHE;
this.removeChild(_pic);
_loader.visible
= false;
debug(
"图片已经准备!");
break;
case Event.OPEN:
if(state == STATE_UPLOAD){
debug(
"正在上传图片...");
}
break;
case ProgressEvent.PROGRESS:
if (state == STATE_UPLOAD) {
var pEvent:ProgressEvent = event as ProgressEvent;
_progress.setProgress(pEvent.bytesLoaded, pEvent.bytesTotal);
}
break;
case SecurityErrorEvent.SECURITY_ERROR:
case IOErrorEvent.IO_ERROR:
case HTTPStatusEvent.HTTP_STATUS:
if (state == STATE_UPLOAD) {
debug(
"图片上传失败!");
_buttons[
0].enabled = true;
_buttons[
1].enabled = true;
}
else {
debug(
"图片缓冲失败!");
}
_progress.setProgress(
0, 1);
result
= "[00]-[上传失败]";
break;

}
if (result!='' && ExternalInterface.available)
{
ExternalInterface.call(_upload_complete_callback, result);
}
}

private
function getButton(lbl:String,width:uint=120):Button {
var button:Button = new Button();
button.label
= lbl;
button.setSize(width,
34);
button.setStyle(
"textFormat", getTextFormat());
button.setStyle(
"disabledTextFormat", getTextFormat(0x999999));
button.setStyle(
"textPadding",4);
button.addEventListener(MouseEvent.CLICK, clickHandler);
this.addChild(button);
_buttons.push(button);
return button;
}

private
function getLabel(label:String, format:TextFormat, isHand:Boolean=false,selectable:
Boolean
= false, autoSize:Boolean = true):TextField {
var lbl:TextField = new TextField();
lbl.selectable
= selectable;
lbl.defaultTextFormat
= format;
if(autoSize){
lbl.autoSize
= TextFieldAutoSize.LEFT;
}
if (isHand) lbl.htmlText = "<a href=\"#\">" + label + "</a>";
else lbl.text = label;
return lbl;
}

private
function getTextFormat(color:uint=0x000000,size:uint = 16,bold:Boolean=false,underline:Boolean=false):
TextFormat {
var format:TextFormat = new TextFormat();
format.font
= "宋体";
format.color
= color;
if(underline)format.underline = true;
format.size
= size;
format.bold
= bold;
return format;
}

private
function getTextFormatWithUnderline(color:uint=0x000000,size:uint = 16,bold:Boolean=false):
TextFormat {
var format:TextFormat = new TextFormat();
format.font
= "宋体";
format.color
= color;
format.underline
= true;
format.size
= size;
format.bold
= bold;
return format;
}

private
function getLabelFilter(color:uint=0xFFFFFF):BitmapFilter {
var alpha:Number = 0.8;
var blurX:Number = 2;
var blurY:Number = 2;
var strength:Number = 3;
var inner:Boolean = false;
var knockout:Boolean = false;
var quality:Number = BitmapFilterQuality.HIGH;

return new GlowFilter(color,
alpha,
blurX,
blurY,
strength,
quality,
inner,
knockout);
}

private
function date2str(day:Date):String {
var str:String = day.getFullYear() + "-";
str
+= num2str(day.getMonth() + 1) + "-";
str
+= num2str(day.getDate()) + " ";
str
+= num2str(day.getHours()) + ":";
str
+= num2str(day.getMinutes()) + ":";
str
+= num2str(day.getSeconds());
return str;
}

private
function num2str(val:Number):String {
var str:String = "00" + val;
return str.substr(str.length - 2, 2);
}

private
function debug(message:String):void {
_state_txt.text
= message;
}
}

}

可很明显看到,源码是AS3编写的,IDE选择使用FlashDevelop,开源软件。
环境:Flash CS4、net framework 2.、Flex SDK4.0、Java SDK 1.6、FlashDevelop


关键点:
1.获取外部参数通过stage.loaderInfo.parameter["Name"]
2.外部JS执行AS内部方法通过ExternalInterface.addCallback("outerEvent", outerEventCallback)
3.AS内部回调外部JS函数通过ExternalInterface.call("outerFunc", "arguments");

posted @ 2011-07-13 10:00  T#S  阅读(2684)  评论(1编辑  收藏  举报