加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Flex多图片压缩上传

发布时间:2020-12-15 04:42:25 所属栏目:百科 来源:网络整理
导读:前段时间按照公司要求做了一个Flex多图片压缩上传组件,使网站实现了图片的快速上传与分享,提高了用户体验。 使用Flex4开发, Flex好像没有自带的多线程功能,因此借用了 ? 开源项目async-threading实现多线程并发上传。 google code地址:http://code.goog

前段时间按照公司要求做了一个Flex多图片压缩上传组件,使网站实现了图片的快速上传与分享,提高了用户体验。

使用Flex4开发,Flex好像没有自带的多线程功能,因此借用了?开源项目async-threading实现多线程并发上传。

google code地址:http://code.google.com/p/async-threading/

要在flex4 sdk环境下使用,要先修改一下源代码,打开com.symantec.premiumServices.asyncThreading.handlers.FPSObserverHandler


将import mx.core.Application; 修改为import spark.components.Application;


将private var _appRef:Application = Application.applicationas Application;修改为private var _appRef:Application = FlexGlobals.topLevelApplication as Application;


同时导入import mx.core.FlexGlobals;
????????这个api要求自定义的线程继承AbstractAsyncThread然后实现IAsyncThreadResponder接口。

首先自定义一个?CommendThread.as

package?common
{
	import?com.symantec.premiumServices.asyncThreading.abstract.AbstractAsyncThread;
	import?com.symantec.premiumServices.asyncThreading.interfaces.IAsyncThreadResponder;
	public?class?CommendThread?extends?AbstractAsyncThread?implements?IAsyncThreadResponder
	{
		private?var?_f:Function;
		public?function?CommendThread(f:Function)
		{
			this._f?=?f;
		}
		public?function?execute():void
		{
			_f.call();
			this.kill();
		}
	}
}


定义图片组件?MyImage.mxml

<?xml?version="1.0"?encoding="utf-8"?>
<s:ItemRenderer?xmlns:fx="http://ns.adobe.com/mxml/2009"?
				xmlns:s="library://ns.adobe.com/flex/spark"?
				xmlns:mx="library://ns.adobe.com/flex/mx"?
				autoDrawBackground="true">
	<fx:Script>
		<![CDATA[
			import?mx.controls.Alert;
		]]>
	</fx:Script>
	<s:Image?width="100"?height="100">
		<s:creationComplete>
			<![CDATA[
			var?img:Image?=?event.target?as?Image;
			var?file:FileReference?=?data?as?FileReference;
			img.source?=?file.data;
			]]>
		</s:creationComplete>
	</s:Image>
	<s:Image?x="84"?y="0"?width="16"?height="15"?source="@Embed('close_btn.png')">
		<s:click>
			<![CDATA[
			parentDocument.valiUpload();
			var?file:FileReference?=?data?as?FileReference;
			parentDocument.removeImageArray(file);?
			]]>
		</s:click>
		<s:mouSEOver>
			<![CDATA[
			Mouse.cursor?=?MouseCursor.BUTTON;
			]]>
		</s:mouSEOver>
		<s:mouSEOut>
			<![CDATA[
			Mouse.cursor?=?MouseCursor.ARROW;
			]]>
		</s:mouSEOut>
	</s:Image>
</s:ItemRenderer>



主文件?flexMultiUpload.mxml

<?xml?version="1.0"?encoding="utf-8"?>
<s:Application?xmlns:fx="http://ns.adobe.com/mxml/2009"
			???xmlns:s="library://ns.adobe.com/flex/spark"
			???xmlns:mx="library://ns.adobe.com/flex/mx"
			???width="700"?height="450"?minWidth="955"?minHeight="600"?initialize="init()">
	<fx:Style>
		@namespace?s?"library://ns.adobe.com/flex/spark";
		@namespace?mx?"library://ns.adobe.com/flex/mx";
		.back
		{
			backgroundColor:#E7E7E7;
			borderAlpha:0;
		}
	</fx:Style>
	<fx:Script>
		<![CDATA[
			import?common.CommendThread;
			
			import?mx.collections.ArrayCollection;
			import?mx.controls.Alert;
			import?mx.graphics.codec.JPEGEncoder;
			import?mx.utils.StringUtil;
			
			import?spark.components.Image;
			
			
			private?var?fileRef:FileReferenceList?=?new?FileReferenceList();
			
			[Bindable]
			private?var?imageArray:ArrayCollection?=?new?ArrayCollection;//图片数组	
			private?var?imageNameArray:ArrayCollection?=?new?ArrayCollection;//上传图片名称数组
			
			private?var?uploadURL:String?=?"http://www.leku.com/flex/flexuploadimage?";
			private?var?header:URLRequestHeader?=?new?URLRequestHeader("Content-type",?"application/octet-stream");
			private?var?isUploading:Boolean?=?false;
			
			//初始化
			public?function?init():void
			{
				//初始化图片上传的url
				var?url:String?=?this.parameters.url;
				if(url?!=?null?&&?url.length>0)
				{
					uploadURL?=?decodeURI(this.parameters.url);
				}
				
				//初始化文件选择事件
				fileRef.addEventListener(Event.SELECT,selectFileHandler);
				fileRef.addEventListener(Event.COMPLETE,completeFileHandler);
			}
			
			public?function?valiUpload():void
			{
				if(isUploading)
				{
					Alert.show("正在上传中,请稍后操作。");
					throw?new?Error("正在上传中,请稍后操作。");
				}
			}
			
			
			//打开图片选择框
			private?function?showSelectDialog():void
			{
				valiUpload();
				fileRef.browse([
					new?FileFilter("Images?(*.jpg,?*.jpeg,?*.gif,?*.png)",?"*.jpg;*.jpeg;*.gif;*.png")
				]);
			}
			
			
			//图片选择完成后
			private?function?selectFileHandler(e:Event):void
			{
				for?each?(var?file:FileReference?in?fileRef.fileList)?
				{
					if(imageNameArray.contains(file.name))
					{
						continue;
					}
					file.load();
					file.addEventListener(Event.COMPLETE,completeFileHandler);
				}
				uploadButton.visible?=?true;
			}
			
			
			//图片加载完成后
			private?function?completeFileHandler(e:Event):void
			{
				var?file:FileReference?=?e.target?as?FileReference;
				insertImageArray(file);
			}
			
			
			//图片数组增加元素
			private?function?insertImageArray(file:FileReference):void
			{
				imageArray.addItem(file);
				imageNameArray.addItem(file.name);
			}
			
			
			//删除图片数组元素
			public?function?removeImageArray(file:FileReference):void
			{
				var?index:Number?=?imageArray.getItemIndex(file);
				if(index?>=?0)
				{
					imageArray.removeItemAt(index);
				}
				index?=?imageNameArray.getItemIndex(file.name);
				if(index?>=?0)
				{
					imageNameArray.removeItemAt(index);
				}
			}
			
			
			
			private?var?value:Number?=?0;
			private?var?total:Number?=?0;
			private?var?index:Number?=?0;
			private?var?maxSize:Number?=?1024;//设置图片压缩尺寸
			
			//上传图片
			private?function?upload():void
			{
				if(imageArray.length?<=?0)
				{
					Alert.show("请选择图片");
					return;
				}
				valiUpload();
				isUploading?=?true;
				value?=?0;
				total?=?imageArray.length;
				progressBar.visible?=?true;
				progressBar.setProgress(value,total);
				for?each?(var?file:FileReference?in?imageArray)?
				{
					uploading(file);	
				}
				
			}
			
			private?function?uploading(file:FileReference):void
			{
				new?CommendThread(function():void
				{
					var?fileName:String?=?file.name;
					var?loader:Loader?=?new?Loader();
					loader.contentLoaderInfo.addEventListener(Event.COMPLETE,?function():void
					{
						var?bm:Bitmap=loader.content?as?Bitmap;
						var?bmd:BitmapData;
						if((bm.width>=bm.height)&&bm.width>maxSize)
						{
							var?rateW:Number=maxSize/bm.width;
							var?h:Number=rateW*bm.height;
							bmd=new?BitmapData(maxSize,h,true,0);
							bmd.draw(bm.bitmapData,new?Matrix(rateW,rateW),null,true);
							bm=new?Bitmap(bmd,PixelSnapping.ALWAYS,true);
							bmd?=?bm.bitmapData;
						}
						else?if(bm.height>bm.width&&bm.height>maxSize)
						{
							var?rateH:Number=maxSize/bm.height;
							var?w:Number=rateH*bm.width;
							bmd=new?BitmapData(w,maxSize,new?Matrix(rateH,rateH),true);
							bmd?=?bm.bitmapData;
						}
						else
						{
							bmd?=?bm.bitmapData;
						}
						
						
						var?urlLoader:URLLoader?=?new?URLLoader();
						var?jpeg:JPEGEncoder?=?new?JPEGEncoder(80);
						var?b:ByteArray?=?jpeg.encode(bmd);
						var?subRequest:URLRequest?=?new?URLRequest();
						subRequest.method?=?URLRequestMethod.POST;
						subRequest.requestHeaders.push(header);
						subRequest.url?=?uploadURL+"&fileName="+encodeURI(fileName==null?"":fileName);//url编码,不然汉字会乱码
						subRequest.data?=?b;
						
						urlLoader.load(subRequest);??
						urlLoader.addEventListener(Event.COMPLETE,function(e:Event):void{
							progressBar.setProgress(++value,total);
							ExternalInterface.call("flexCallBack",urlLoader.data);
							if(value?==?total)
							{
								imageArray.removeAll();
								imageNameArray.removeAll();
								value?=?0;
								total?=?0;
								progressBar.visible?=?false;
								ExternalInterface.call("flexCompleteCallBack");
								isUploading?=?false;
							}
//							System.gc();
						});
					});
					loader.loadBytes(file.data);
				}).start();
			}
			
			
		]]>
	</fx:Script>
	<s:VGroup?x="0"?y="0"?width="700"?height="450"?gap="0">
		<s:HGroup?width="700"?height="400"?gap="0">
			<s:Scroller>
				<s:DataGroup?width="684"?height="400"?dataProvider="{imageArray}"
							?focusColor="#EE7091"?itemRenderer="mycomponent.MyImage">
					<s:layout>
						<s:TileLayout?useVirtualLayout="true"??requestedColumnCount="6">
						</s:TileLayout>
					</s:layout>
				</s:DataGroup>
			</s:Scroller>
		</s:HGroup>
		<s:BorderContainer?width="700"?height="50"??styleName="back">
			<s:Button?x="210"?y="8"?width="116"?height="35"?label="选择图片"?click="showSelectDialog()">
				<s:mouSEOver>
					<![CDATA[
					Mouse.cursor?=?MouseCursor.BUTTON;
					]]>
				</s:mouSEOver>
				<s:mouSEOut>
					<![CDATA[
					Mouse.cursor?=?MouseCursor.ARROW;
					]]>
				</s:mouSEOut>
			</s:Button>
			<s:Button?x="370"?y="8"?width="116"?height="35"?label="图片上传"??click="upload()"?id="uploadButton"?visible="false">
				<s:mouSEOver>
					<![CDATA[
					Mouse.cursor?=?MouseCursor.BUTTON;
					]]>
				</s:mouSEOver>
				<s:mouSEOut>
					<![CDATA[
					Mouse.cursor?=?MouseCursor.ARROW;
					]]>
				</s:mouSEOut>
			</s:Button>
		</s:BorderContainer>
	</s:VGroup>
	<mx:ProgressBar?x="150"?y="200"?width="400"?id="progressBar"?mode="manual"?labelPlacement="center"?label="%1?of?%2,总进度:%3%%"?visible="false">
		
	</mx:ProgressBar>
</s:Application>


以下是工程结构


这是close_btn.png的图片: ?


接下来就是要导出swf文件了,如果方式不对的话,会导致文件很大,从何造成网页组件加载很慢。

我是用的是flash builder开发,流程如下

右键点击工程-->选择Properties -->选择 Flex Build Path-->选择RSL选择,这样编译的时候只会加载使用到的类库,大大

降低swf文件大小-->点击OK


点击Export Release Build



选择工程,然后点击finish,完成后在bin-release目录下找到flexMultiUpload.swf



可以使用浏览器直接打开,或者flash客户端(尽量把flash更新到最新版本)

服务端使用java struts2

import?java.io.File;
import?java.io.InputStream;
import?javax.servlet.http.HttpServletRequest;
import?javax.servlet.http.HttpServletResponse;
import?org.apache.commons.io.FileUtils;
import?org.apache.struts2.ServletActionContext;
import?org.apache.struts2.convention.annotation.Action;
import?com.opensymphony.xwork2.ActionSupport;

public?class?FlexAction??extends?ActionSupport{
	

	/**
	?*?
	?*/
	private?static?final?long?serialVersionUID?=?-3543364166243030722L;
	private?HttpServletRequest?request?=?ServletActionContext.getRequest();
	private?HttpServletResponse?response?=?ServletActionContext.getResponse();
	public?static?final?Integer?MAX_SIZE?=?1024*1024*2;//允许图片最大尺寸
	
	private?String?fileName;
	
	@Action(value?=?"flexuploadimage")
	public?String?upload()?throws?Exception{
		
		InputStream?inputStream?=?request.getInputStream();
		int?formlength?=?request.getContentLength();
		
		//如果图片大于允许的值
		if(formlength?>?MAX_SIZE){
			//返回异常信息
			response.getOutputStream().println("自定义返回信息,或者跳转到异常页面");
			return?null;
		}
		
		
		byte[]?formcontent?=?new?byte[formlength];
		int?totalread?=?0;
		int?nowread?=?0;
		while?(totalread?<?formlength)?{
			nowread?=?inputStream.read(formcontent,?totalread,?formlength);
			totalread?+=?nowread;
		}
		
		//将图片写入本地或者图片服务器
		File?file?=?new?File("D:/flex",?fileName);
		FileUtils.writeByteArrayToFile(file,?formcontent);
		
		return?null;
	}

	public?String?getFileName()?{
		return?fileName;
	}

	public?void?setFileName(String?fileName)?{
		this.fileName?=?fileName;
	}

	


}


jsp页面调用


<%@page?import="java.net.URLEncoder"%>
<%@?page?language="java"?contentType="text/html;?charset=UTF-8"?pageEncoding="UTF-8"%>
<%@?taglib?prefix="c"?uri="http://java.sun.com/jsp/jstl/core"?%>
<%@?taglib?prefix="fmt"?uri="http://java.sun.com/jsp/jstl/fmt"?%>
<%@?taglib?prefix="fn"?uri="http://java.sun.com/jsp/jstl/functions"?%>
<%
request.setAttribute("url",?URLEncoder.encode("上传路径",?"utf-8"));
%>
<div?style="height:600px;width:800px;display:table-cell;vertical-align:middle;text-align:center;">
	<embed?src="flexMultiUpload.swf"?style="height:450px;width:700px;border:?#C9DDEA?solid?1px;vertical-align:?middle;"?flashVars="url=${url?}"?allowScriptAccess="always">
	<br/>
	<div?style="margin-left:?-450px;margin-top:?10px;">
		<span>如果不能正常使用,请将Flash升级到最新版本。</span>
	</div>
</div>


组件缺陷(由于本文作者偷懒的结果,哈哈):

每一个图片新开一个线程并发上传,如果用户一次性上传的图片过多,可能会造成客户端挂掉的现象。

解决办法:(1)限制每次上传的图片数量

(2)做一个上传队列,几个线程并发执行队列中的任务(可以参考QQ空间相册普通上传功能,注意:不是极速上传)。

(3)flex的多线程是借助于第三方的

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读