flex 与 flash 插件 相片编辑器
as project与flex 工程在编译后,swf大小相差10倍
flex: 208704 字节
as3: 19271 字节
使用rsl分解也比as工程要大5倍左右,并且首次下载差距将变为500倍。 如果项目对贷款的要求比较严格可以使用纯as工程来缩减。
flex工程源码:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" usePreloader="false"
preinitialize="getWrapperInfo()" backgroundColor="white" fontSize="12"
backgroundGradientColors="[0xffffff,0xffffff,0xffffff,0xffffff]">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.controls.Alert;
import mx.binding.utils.BindingUtils;
import mx.core.UIComponent;
private function getWrapperInfo():void{
Debug.warning("v1010191725");
Application.application.addEventListener(ErrorEvent.ERROR, unknowException);
Sysvo.fill(Application.application.parameters);
}
private function unknowException(e:ErrorEvent):void{
Debug.error("get unknow exception:"+e.toString());
}
private function dragHandler(e:Event):void{
var btm:UIComponent = ComponentCopy.copyToUIComponent(
cavViewPort.width, cavViewPort.height, -1*cavViewPort.x , -1*cavViewPort.y, cavContent);
cav99.graphics.beginBitmapFill(ComponentCopy.snapshotScale(99, 99, btm));
cav99.graphics.drawRect(0,0,99,99);
cav99.graphics.endFill();
cav66.graphics.beginBitmapFill(ComponentCopy.snapshotScale(66, 66, btm));
cav66.graphics.drawRect(0,0,66,66);
cav66.graphics.endFill();
cav33.graphics.beginBitmapFill(ComponentCopy.snapshotScale(33, 33, btm));
cav33.graphics.drawRect(0,0,33,33);
cav33.graphics.endFill();
}
private function rotate(doRight:Boolean=true):void{
if(effRotate.isPlaying)
return ;
effRotate.angleFrom = imgTest.rotation;
effRotate.angleTo = imgTest.rotation + (doRight ? 90 : -90);
effRotate.play([imgTest]);
}
private function itemScale(isAdd:Boolean=true):void{
if( (imgTest.scaleX > 4 && isAdd == true) || (imgTest.scaleX <= 0.25 && isAdd == false)){
return;
}else{
imgTest.scaleY = imgTest.scaleX += isAdd ? 0.1 : -0.1;
dragHandler(null);
}
}
private function imgContentCreated():void{
IConDragAct.bangding(imgTest, cavContent.x, cavContent.y);
imgTest.loaderContext = new LoaderContext(true);//sescurity.
imgTest.addEventListener(IConDragAct.DRAG_MOVE, dragHandler);//drag end. redraw image.
labInfo.text = Uploader.instance.uploadInfo;//show info
Uploader.instance.addEventListener(Event.COMPLETE, userUploadIconComplete);
imgTest.addEventListener(Event.COMPLETE,function(e:Event):void{
Debug.warning("image complete");
resetImg();
imgTest.addEventListener(FlexEvent.UPDATE_COMPLETE, autoScale);
labCancel.enabled = btnSave.enabled = true;
});
if(Sysvo.hasPicUrl!=null && Sysvo.hasPicUrl.length > 4){
Uploader.instance.uploadInfo = "";
imgTest.load(Sysvo.hasPicUrl);
labCancel.enabled = btnSave.enabled = true;
}else{
labCancel.enabled = btnSave.enabled = false;
}
}
private function autoScale(e:Event=null):void{
imgTest.removeEventListener(FlexEvent.UPDATE_COMPLETE, autoScale);
if(imgTest.content.width > 0 &&
(imgTest.width < cavViewPort.width || imgTest.height < cavViewPort.height)){
var baseline:int = imgTest.width >= imgTest.height ? imgTest.height : imgTest.width;
var scalev:Number = (cavViewPort.width - cavViewPort.getStyle("borderThickness"))/baseline;
Debug.warning(scalev+ "," +imgTest.width +","+ imgTest.height);
imgTest.scaleX = imgTest.scaleY = scalev;
imgTest.callLater(dragHandler,[e]);
}
}
private function selectHandler():void{
Uploader.instance.img = imgTest;
BindingUtils.bindProperty(labInfo,"text", Uploader.instance, "uploadInfo");
Uploader.instance.url = Sysvo.firstUploadUrl;
try{
Uploader.instance.selectFile();
}catch(e:Error){
Debug.error(e.getStackTrace());
}
}
private function uploadViewPort():void{
try{
var bitmapdata:BitmapData = ComponentCopy.copy(
cavViewPort.width-4, cavViewPort.height-4, -1*cavViewPort.x-3 , -1*cavViewPort.y-3, cavContent);
Uploader.instance.uploadBitmapData(bitmapdata, Sysvo.fixUploadUrl);
}catch(e:Error){
Debug.log(e.getStackTrace(), Debug.RED);
}
}
public function resetImg():void{
imgTest.scaleY = imgTest.scaleX = 1;
imgTest.rotation = 0;
imgTest.x = cavViewPort.x + 2;
imgTest.y = cavViewPort.y + 2;
}
public function labCancelHandler():void{
if(btnSave.enabled){
resetImg()
var e:Event = new Event("");
imgTest.callLater(dragHandler, [e]);
}
}
public function userUploadIconComplete(e:Event):void{
Sysvo.completeCallJavascript();
}
]]>
</mx:Script>
<mx:HBox backgroundColor="#F3F3F3" x="10" y="25" width="500" height="30" verticalAlign="middle"
useHandCursor="true" mouseChildren="false" buttonMode="true" click="selectHandler()">
<mx:Spacer width="1" />
<mx:TextInput />
<mx:Button upSkin="@Embed(source='uploading_bt02.png')" downSkin="@Embed(source='uploading_bt01.png')"
overSkin="@Embed(source='uploading_bt02.png')" />
<mx:Label text="支持jpg,gif,png格式,文件小于2M" color="#999999" />
</mx:HBox>
<mx:Canvas id="cavContent" x="10" y="65" width="350" height="350" borderThickness="1" cacheAsBitmap="{true}"
borderStyle="solid" borderColor="#D4D4D4" horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:Image x="90" y="90" id="imgTest" cacheAsBitmap="{true}"
creationComplete="imgContentCreated()" />
<mx:HBox horizontalGap="0" x="10" y="10">
<mx:Canvas id="cavZin" borderSkin="@Embed(source='zoom in.png')" width="28" height="22" click="itemScale()" useHandCursor="true" buttonMode="true"/>
<mx:Canvas id="cavZout" borderSkin="@Embed(source='zoom out.png')" width="28" height="22" click="itemScale(false)" useHandCursor="true" buttonMode="true"/>
<mx:Canvas id="cavRtleft" borderSkin="@Embed(source='anticlockwise.png')" width="28" height="22" click="rotate(false)" useHandCursor="true" buttonMode="true"/>
<mx:Canvas id="cavRtright" borderSkin="@Embed(source='clockwise.png')" width="28" height="22" click="rotate()" useHandCursor="true" buttonMode="true"/>
</mx:HBox>
<mx:Canvas id="cavViewPort" borderColor="#FFAA01" borderStyle="solid" borderThickness="2" x="90" y="90" width="192" height="192" />
</mx:Canvas>
<mx:UIComponent id="cav99" x="368" y="63" width="99" height="99"/>
<mx:UIComponent id="cav66" x="368" y="175" width="66" height="66" />
<mx:UIComponent id="cav33" x="368" y="251" width="33" height="33" />
<mx:Button x="10" y="425" id="btnSave" click="uploadViewPort()"
upSkin="@Embed(source='save_bt02.png')" downSkin="@Embed(source='save_bt01.png')"
overSkin="@Embed(source='save_bt02.png')" disabledSkin="@Embed(source='save_bt02.png')"
useHandCursor="true" buttonMode="true" mouseChildren="false"/>
<mx:Label id="labCancel" click="labCancelHandler();" color="#008FDD" y="430" x="135" text="撤销操作"
useHandCursor="true" mouseChildren="false" buttonMode="true"/>
<mx:Label id="labInfo" y="430" x="208" />
<mx:Rotate id="effRotate" duration="100" effectEnd="dragHandler(null)" tweenUpdate="dragHandler(null)" />
</mx:Application>
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.IBitmapDrawable;
import flash.geom.Matrix;
import flash.geom.Point;
import mx.core.UIComponent;
public class ComponentCopy
{
public function ComponentCopy() { }
/**
* 截取目标控件的部分或全部
* */
public static function copy(width:Number, height:Number, xStart:Number,
yStart:Number, target:IBitmapDrawable):BitmapData{
var bmpData:BitmapData = new BitmapData(width, height, true);
var m:Matrix = new Matrix(1, 0, 0, 1, xStart, yStart);
bmpData.draw(target, m);
return bmpData;
}
public static function copyToUIComponent(width:Number, height:Number, xStart:Number,
yStart:Number, target:IBitmapDrawable):UIComponent{
var ui:UIComponent = new UIComponent();
ui.height = height;
ui.width = width;
var bitmap:Bitmap = new Bitmap(copy(width, height, xStart, yStart, target));
ui.addChild(bitmap);
return ui;
}
/**
* 将目标空间缩放到指定的尺寸后快照
* width: 缩放结果的宽
* height: 缩放结果的高
* */
public static function snapshotScale(width:Number, height:Number, target:IBitmapDrawable):BitmapData{
var p:Point = prepearScaleXY(width, height, UIComponent(target));
var bmpData:BitmapData = new BitmapData(width, height, true);
var m:Matrix = new Matrix(p.x, 0,0, p.y, 0,0);
bmpData.draw(target, m);
return bmpData;
}
private static function prepearScaleXY(width:Number, height:Number, target:DisplayObject):Point{
var p:Point = new Point();
p.x = width/target.width;
p.y = height/target.height;
return p;
}
}
}
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import mx.core.UIComponent;
public class IConDragAct
{
private var ui:UIComponent;
private var fixeXVal:Number = 0;
private var fixeYVal:Number = 0;
private var isDraging:Boolean = false;
private var cx:int = 0;
private var cy:int = 0;
public static const DRAG_MOVE:String="DRAG_MOVE";
public static function bangding(c:UIComponent, containerX:Number=0, containerY:Number=0):IConDragAct{
return new IConDragAct(c, containerX, containerY);
}
public function IConDragAct(c:UIComponent, containerX:Number=0, containerY:Number=0)
{
this.ui = c;
c.addEventListener(MouseEvent.MOUSE_DOWN, doDrag);
c.addEventListener(MouseEvent.MOUSE_UP, doDrag);
c.addEventListener(MouseEvent.MOUSE_MOVE, move);
cx = containerX;
cy = containerY;
}
private function doDrag(e:MouseEvent):void{
if(e.type == MouseEvent.MOUSE_DOWN){
if(ui.rotation == 0){
fixeXVal = e.localX* ui.scaleX + cx ;
fixeYVal = e.localY* ui.scaleY + cy ;
}else if(ui.rotation == 90){
fixeXVal = e.stageX - ui.x;
fixeYVal = e.stageY - ui.y;
}else if(ui.rotation == 180){
fixeXVal = (-e.localX)* ui.scaleX + cx;
fixeYVal = (-e.localY)* ui.scaleY + cy;
}else if(ui.rotation == 270 || ui.rotation == -90){
fixeXVal = e.stageX - ui.x;
fixeYVal = e.stageY - ui.y;
}else{
// trace("waring::", ui.rotation);
}
// trace(fixeXVal, fixeYVal, ui.x, ui.y, e.localX, e.localY, e.stageX, e.stageY); // test
isDraging = true;
}else{
fixeXVal = fixeYVal = 0;
isDraging = false;
}
}
private function move(e:MouseEvent):void{
e.stopImmediatePropagation();
e.stopPropagation();
if(e.buttonDown && targetLocalCanGrag(e)){
ui.dispatchEvent(new Event(DRAG_MOVE));
ui.move(e.stageX - fixeXVal, e.stageY - fixeYVal);
}
}
private function targetLocalCanGrag(e:MouseEvent):Boolean{
// if()
return true;
}
}
}
package
{
import flash.external.ExternalInterface;
public class Sysvo
{
public static var firstUploadUrl:String; //第一次上传图片的url
public static var fixUploadUrl:String; //上传修改后的图片的url
public static var fileParm:String; //上传图片时文件的参数名
public static var faildCallBack:String; //上传失败后回调js函数名
public static var okCallBack:String; //上传成功后js的回调函数
public static var ortherValue:String; //上传时同时附加的参数值
public static var ortherName:String; //上传时同时附加的参数名
public static var hasPicUrl:String; //已经有的图片,可以继续修改
public static var maxSize:Number; //上传单个文件最大值
public static const DEFAULT_FIXURL:String = "http://localhost:9999/mt/uploadTest";
public static const DEFAULT_FILEPARAM:String = "fileData";
public static const DEFAULT_SIZE:int = 1024 * 1024 * 2; //2m
public static const MAXSIZE:int = 1024 * 1024 * 50; //50m
public static function fill(appparam:Object):void{
firstUploadUrl = appparam["up1url"]==null ? DEFAULT_FIXURL : appparam["up1url"];
fixUploadUrl = appparam["fixurl"]==null ? DEFAULT_FIXURL : appparam["fixurl"];
fileParm = appparam["fp"]==null ? DEFAULT_FILEPARAM : appparam["fp"];
Debug.log("up1url="+firstUploadUrl+", fixUploadUrl="+fixUploadUrl+", fileParm="+fileParm);
faildCallBack = appparam["faildCallBack"];
okCallBack = appparam["okCallBack"];
ortherValue = appparam["ortherValue"];
ortherName = appparam["ortherName"];
hasPicUrl = appparam["hasPicUrl"];
Debug.log("faildCallBack="+faildCallBack+", okCallBack="+okCallBack
+", ortherValue="+ortherValue +", ortherName="+ortherName +
", hasPicUrl="+hasPicUrl);
maxSize = checkSize(appparam["maxSize"]) ? appparam["maxSize"] : DEFAULT_SIZE ;
Debug.log("maxSize="+maxSize);
}
public static function checkSize(size:Object):Boolean{
try{
if(size == null ||
int(size) <= 0 ||
int(size) > MAXSIZE){
return false;
}
return true;
}catch(e:Error){
return false;
}
return false;
}
public static function getOrtherParamObj():Object{
var p:Object = null
if(ortherName != null){
p = new Object();
p[ortherName] = ortherValue;
}
return p;
}
public static function completeCallJavascript():Boolean{
try{
if(Sysvo.okCallBack != null && Sysvo.okCallBack.length > 0){
ExternalInterface.call(Sysvo.okCallBack);
return true;
}
return false;
}catch(e:Error){
Debug.error("Sysvo.completeCallJavascript::"+e.getStackTrace());
}
return false;
}
public static function errCallJavascript():Boolean{
try{
if(Sysvo.faildCallBack != null && Sysvo.faildCallBack.length > 0){
ExternalInterface.call(Sysvo.faildCallBack);
return true;
}
return false;
}catch(e:Error){
Debug.error("Sysvo.errCallJavascript"+e.getStackTrace());
}
return false;
}
}
}
package
{
import flash.display.BitmapData;
import flash.events.DataEvent;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod;
import flash.utils.ByteArray;
import mx.controls.Image;
import mx.graphics.codec.JPEGEncoder;
public class Uploader extends EventDispatcher
{
private var typeAry:Array=["jpg","png"];
public var url:String = "";
private var fr:FileReference = new FileReference();;
public var img:Image;
public static const instance:Uploader = new Uploader();
[Bindable]
public var uploadInfo:String = "";
public static const UPLOADED:String = "UPLOADED";
private var urlLoader:URLLoader = new URLLoader();
private var defaultFileter:FileFilter = new FileFilter("Images", "*.jpg;*.gif;*.png");
public function Uploader() {
fr.addEventListener(Event.SELECT, selectHandler);
fr.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadComplete);
fr.addEventListener(IOErrorEvent.IO_ERROR, errHandler);
fr.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errHandler);
}
private function selectHandler(e:Event):void{
var urlq:URLRequest = new URLRequest();
urlq.url = url;
if(fr.size > Sysvo.maxSize){
uploadInfo = "文件不能大于"+ Number(Sysvo.maxSize/1024).toFixed(4) + "KB";
return;
}
uploadInfo = "正在上传...";
fr.upload( urlq, Sysvo.fileParm, true );
}
public function selectFile(type:Array=null):void{
if(type == null){
type = [defaultFileter];
}
fr.browse( type );
}
private function uploadComplete(e:DataEvent):void{
if(img){
uploadInfo = "上传成功 正在加载新图";
img.load(e.data);
}else{
uploadInfo = "上传成功";
dispatchEvent(new DataEvent(UPLOADED, false, false, e.data));
}
}
public function errHandler(e:Event):void{
Debug.error("upload faild:"+IOErrorEvent(e).text + e.toString() + ", url=" + url);
uploadInfo = "上传失败";
Sysvo.errCallJavascript();
}
/**
*
* */
public function uploadBitmapData(b:BitmapData, url:String):void{
uploadInfo = "正在上传";
var encoder:JPEGEncoder = new JPEGEncoder(80);
var bitAry:ByteArray = encoder.encode(b);
var urlRequest:URLRequest = new URLRequest();
urlRequest.url = url;
urlRequest.contentType = 'multipart/form-data; boundary='+UploadPostHelper.getBoundary();
urlRequest.data = UploadPostHelper.getPostData( 'image.jpg', bitAry, Sysvo.getOrtherParamObj(), Sysvo.fileParm );
urlRequest.method = URLRequestMethod.POST;
urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, errHandler)
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,errHandler);
urlLoader.addEventListener(Event.COMPLETE, fixupLoaderOver);
urlLoader.load(urlRequest);
}
private function fixupLoaderOver(e:Event):void{
uploadInfo = "头像上传成功";
dispatchEvent(new Event(Event.COMPLETE, false, false));
}
}
}
/* AS3
Copyright 2007 Jonathan Marston
*/
package
{
/**
* Take a fileName, byteArray, and parameters object as input and return ByteArray post data suitable for a UrlRequest as output
*
* @see http://marstonstudio.com/?p=36
* @see http://www.w3.org/TR/html4/interact/forms.html
* @see http://www.jooce.com/blog/?p=143
* @see http://www.jooce.com/blog/wp%2Dcontent/uploads/2007/06/uploadFile.txt
* @see http://blog.je2050.de/2006/05/01/save-bytearray-to-file-with-php/
*
* @author Jonathan Marston
* @version 2007.08.19
*
* This work is licensed under a Creative Commons Attribution NonCommercial ShareAlike 3.0 License.
* @see http://creativecommons.org/licenses/by-nc-sa/3.0/
*
*/
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class UploadPostHelper
{
//--------------------------------------
// PUBLIC METHODS
//--------------------------------------
/**
* Boundary used to break up different parts of the http POST body
*/
private static var _boundary:String = "";
/**
* Get the boundary for the post.
* Must be passed as part of the contentType of the UrlRequest
*/
public static function getBoundary():String {
if(_boundary.length == 0) {
for (var i:int = 0; i < 0x20; i++ ) {
_boundary += String.fromCharCode( int( 97 + Math.random() * 25 ) );
}
}
return _boundary;
}
/**
* Create post data to send in a UrlRequest
*/
public static function getPostData(fileName:String,
byteArray:ByteArray, parameters:Object = null, fileFormParam:String="Filedata"):ByteArray {
var i:int;
var bytes:String;
var postData:ByteArray = new ByteArray();
postData.endian = Endian.BIG_ENDIAN;
//add Filename to parameters
if(parameters == null) {
parameters = new Object();
}
parameters.Filename = fileName;
//add parameters to postData
for(var name:String in parameters) {
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Disposition: form-data; name="' + name + '"';
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
postData.writeUTFBytes(parameters[name]);
postData = LINEBREAK(postData);
}
//add Filedata to postData
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
//bytes = 'Content-Disposition: form-data; name="Filedata"; filename="';
bytes = "Content-Disposition: form-data; name=\""+ fileFormParam +"\"; filename=\"";
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData.writeUTFBytes(fileName);
postData = QUOTATIONMARK(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Type: application/octet-stream';
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
postData.writeBytes(byteArray, 0, byteArray.length);
postData = LINEBREAK(postData);
//add upload filed to postData
postData = LINEBREAK(postData);
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Disposition: form-data; name="Upload"';
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
bytes = 'Submit Query';
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
//closing boundary
postData = BOUNDARY(postData);
postData = DOUBLEDASH(postData);
return postData;
}
//--------------------------------------
// EVENT HANDLERS
//--------------------------------------
//--------------------------------------
// PRIVATE & PROTECTED INSTANCE METHODS
//--------------------------------------
/**
* Add a boundary to the PostData with leading doubledash
*/
private static function BOUNDARY(p:ByteArray):ByteArray {
var l:int = UploadPostHelper.getBoundary().length;
p = DOUBLEDASH(p);
for (var i:int = 0; i < l; i++ ) {
p.writeByte( _boundary.charCodeAt( i ) );
}
return p;
}
/**
* Add one linebreak
*/
private static function LINEBREAK(p:ByteArray):ByteArray {
p.writeShort(0x0d0a);
return p;
}
/**
* Add quotation mark
*/
private static function QUOTATIONMARK(p:ByteArray):ByteArray {
p.writeByte(0x22);
return p;
}
/**
* Add Double Dash
*/
private static function DOUBLEDASH(p:ByteArray):ByteArray {
p.writeShort(0x2d2d);
return p;
}
}
}