以前用过SWFUpload ,功能确实很强大。javaeye上有人发布了这样一篇文章step-by-step多文件WEB批量上传(swfupload)的完美解决方案 有兴趣的朋友可以看一 下。Leeo觉得SWFUpload稍微不足的就是界面的定制,总感觉自己定制出来的界面有点难登大雅之堂。下面Leeo为大家介绍一下,如何使用 FlashFileUpload这个Flash组件来实现多文件上传,并且通过java程序自动生成缩略图和添加水印,FlashFileUpload定 制出来的界面还是挺漂亮的(PS:这个界面是Leeo从UUShare上弄下来的,^_^),先来Show一张效果图:
从上面的图片从可以看出中间有个水印(PS:本博客的Logo),这并不是用Photoshop之类的软件弄上去的,而是通过下面将要讲到的java程序 自动添加的,效果很不错,(*^__^*) 嘻嘻……好,正式开始吧…
第一步:当然是获取flashfileupload.swf这个Flash组件啦,大家可以从这里下载 ,或者其他什么途径得到都行
第二步:编写上传页面的代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String uploadType = (String)request.getParameter("uploadType" );
Long filmid = Long.parseLong((String)request.getParameter("filmid" ));
//out.print(uploadType);
//out.print(filmid);
%>
< object id ="fileUpload"
codebase ="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab#version=10,0,22,87"
height ="310" width ="500" align ="middle"
classid ="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" >
< param name ="_cx" value ="13229" />
< param name ="_cy" value ="8202" />
<%
if ("Video" .equals(uploadType)){
%>
< param name ="flashvars" value ="fileTypeDescription=允许视频格式&fileTypes=*.asx;*.asf;*.mpg;*.wmv;*.3gp;*.mp4;*.mov;*.avi;*.flv;*.wmv9;*.rm;*.rmvb&completeFunction=UploadComplete()&fileSizeLimit=3000000&totalUploadSize=10240000&accounttype=0&uploadPage=flashupload!Upload.action;jsessionid=${session.id}?uploadType=<%=uploadType %>-<%=filmid %>" />
<%
}else {
%>
< param name ="flashvars" value ="fileTypeDescription=JPG格式图片&fileTypes=*.jpg;*.jpeg&completeFunction=UploadComplete()&fileSizeLimit=3000000&totalUploadSize=10240000&accounttype=0&uploadPage=flashupload!Upload.action;jsessionid=${session.id}?uploadType=<%=uploadType %>-<%=filmid %>" />
<%
}
%>
< param name ="movie" value ="flashfileupload.swf?ver=20090520" />
< param name ="src" value ="flashfileupload.swf?ver=20090520" />
< param name ="wmode" value ="transparent" />
< param name ="play" value ="0" />
< param name ="loop" value ="-1" />
< param name ="quality" value ="high" />
< param name ="salign" value ="lt" />
< param name ="menu" value ="-1" />
< param name ="base" value ="" />
< param name ="allowscriptaccess" value ="sameDomain" />
< param name ="scale" value ="noscale" />
< param name ="devicefont" value ="0" />
< param name ="embedmovie" value ="0" />
< param name ="bgcolor" value ="" />
< param name ="swremote" value ="" />
< param name ="moviedata" value ="" />
< param name ="seamlesstabbing" value ="1" />
< param name ="profile" value ="0" />
< param name ="profileaddress" value ="" />
< param name ="profileport" value ="0" />
< param name ="allownetworking" value ="all" />
< param name ="allowfullscreen" value ="true" />
<%
if ("Video" .equals(uploadType)){
%>
< embed src ="flashfileupload.swf?ver=20090520"
flashvars ="fileTypeDescription=允许视频格式&fileTypes=*.asx;*.asf;*.mpg;*.wmv;*.3gp;*.mp4;*.mov;*.avi;*.flv;*.wmv9;*.rm;*.rmvb&completeFunction=UploadComplete()&fileSizeLimit=3000000&totalUploadSize=10240000&accounttype=0&uploadPage=flashupload!Upload.action;jsessionid=${session.id}?uploadType=<%=uploadType %>-<%=filmid %>"
quality ="high"
wmode ="transparent"
width ="500"
height ="310"
name ="fileUpload"
align ="middle"
allowscriptaccess ="samedomain"
type ="application/x-shockwave-flash"
pluginspage ="http://www.macromedia.com/go/getflashplayer" >
</ embed >
<%
}else {
%>
< embed src ="flashfileupload.swf?ver=20090520"
flashvars ="fileTypeDescription=JPG格式图片&fileTypes=*.jpg;*.jpeg&completeFunction=UploadComplete()&fileSizeLimit=3000000&totalUploadSize=10240000&accounttype=0&uploadPage=flashupload!Upload.action;jsessionid=${session.id}?uploadType=<%=uploadType %>-<%=filmid %>"
quality ="high"
wmode ="transparent"
width ="500"
height ="310"
name ="fileUpload"
align ="middle"
allowscriptaccess ="samedomain"
type ="application/x-shockwave-flash"
pluginspage ="http://www.macromedia.com/go/getflashplayer" >
</ embed >
<%
}
%>
</ object >
说明:其中主要的是flashvars 这个参数的设置(PS:Leeo本人对这里的设置也仅 仅是略知一二)
fileTypeDescription:允许上传文件的类型描述
fileTypes:允许上传的文件类型
completeFunction:上传完成后调用的js函数
fileSizeLimit:文件大小限制
totalUploadSize:一次性上传文件总大小限制
accounttype:这个没搞清楚怎么用,如果哪位知道的请告知一声,谢谢…
uploadPage:上传文件的请求路径,跟在它后面的是一些用户附加的数据。其中网上有网友说可以;jsessionid=的形式传递 session,Leeo没有做测试。?uploadType=是程序中需要的一些附加数据,这里本来需要两个变量的,之所以把它写到一个变量里,然后用 “-”隔开两个变量值,就像代码中的<%=uploadType %>-<%=filmid %>,是因为我们知道通常通过url传参是用“&”号隔开的,但这里却不能这么做,因为整个flashvars 就 是用“&”来隔开不同参数的,如果附加的数据也用“&”隔开就会被截断,得不到我们想要的数据,所以这里用一种比较马虎的解决方法,利用 “-”号把不同变量值连接起来,然后在服务器端的java代码中用split("-")再把它们分割开来
第三步:配置struts.xml文件,如下:
< package name ="ajaxfileupload" namespace ="/" extends ="ajaxfileupload-default" >
< action name ="flashupload" class ="leeo.action.FlashfileuploadAction" >
< result name ="success" type ="httpheader" >
< param name ="status" > 200</ param >
</ result >
</ action >
</ package >
特别说明: 这里还用到了ajax-file-upload-plugin- 0.4.0.jar(PS:Struts2中用ajxa方式上传文件需要的jar包)
第四步:编写action类代码,如下:
/** 文件对象 */
private transient File[] Filedata;
/** 文件名 */
/** 文件对象 */
private transient File[] Filedata;
/** 文件名 */
private transient String[] FiledataFileName;
/** 文件内容类型 */
private transient String[] FiledataContentType;
/**
* 区分是上传海报、剧照、片花
* **/
private transient String uploadType;
public String Upload() throws Exception {
System.out.println("FiledataFileName length: " + FiledataFileName.length);
System.out.println("uploadType: " + uploadType);
String[] type_filmid = uploadType.split("- ");
System.out.println("filmid: " + type_filmid[1]);
Film f = filmService.findFilmById(new Long(type_filmid[1]));
//原文件存放路径
String OriginalImageDirectory = ServletActionContext.getServletContext().getRealPath("/UploadFile/ " + type_filmid[0] + "/OriginalImage ") + System.getProperty("file.separator ", "// ");
for (int i = 0; i < Filedata.length; i ++){
System.out.println("Filedata[ "+i+"]: " + Filedata[i]);
System.out.println("FiledataFileName[ "+i+"]: " + FiledataFileName[i]);
System.out.println("FiledataContentType[ "+i+"]: " + FiledataContentType[i]);
//在指定目录创建文件
String newname = FileUpload.getFileName(FiledataFileName[i]);
File bigFile = new File(OriginalImageDirectory, newname);
//把要上传的文件copy过去
FileUpload.copy(Filedata[i], bigFile);
if (!"Video ".equals(type_filmid[0])){
//缩略图存放路径
String ThumbnailsDirectory = ServletActionContext.getServletContext().getRealPath("/UploadFile/ " + type_filmid[0] + "/Thumbnails ") + System.getProperty("file.separator ", "// ");
//生成缩略图
FileUpload.scaleImage(OriginalImageDirectory + newname, ThumbnailsDirectory + newname, 180, 200);
//设置数据库海报字段路径
String waterImgFile = ServletActionContext.getServletContext().getRealPath("/UploadFile ") + System.getProperty("file.separator ", "// ");
// 给大图添加文字水印
//FileUpload.watermark(bigFile);
// 给大图添加图片水印,可以是gif或png格式
FileUpload.imageWaterMark(bigFile, waterImgFile);
File smallFile = new File(ThumbnailsDirectory, newname);
// 给大图添加文字水印
//FileUpload.watermark(smallFile);
// 给大图添加图片水印,可以是gif或png格式
FileUpload.imageWaterMark(smallFile, waterImgFile);
}
/*
* 操作数据库部分
* */
if ("Poster ".equals(type_filmid[0])){
f.setFPoster(newname);
filmService.modFilm(f);
}else if ("Still ".equals(type_filmid[0])){
FilmStill fs = new FilmStill();
fs.setFsPath(newname);
fs.setFilm(f);
filmService.addFilmStill(fs);
}else if ("Video ".equals(type_filmid[0])){
FilmVideo fv = new FilmVideo();
fv.setFvPath(newname);
fv.setFilm(f);
filmService.addFilmVideo(fv);
}
}
return SUCCESS;
}
public File[] getFiledata() {
return Filedata;
}
public void setFiledata(File[] filedata) {
this .Filedata = filedata;
}
public String[] getFiledataFileName() {
return FiledataFileName;
}
public void setFiledataFileName(String[] filedataFileName) {
this .FiledataFileName = filedataFileName;
}
public String[] getFiledataContentType() {
return FiledataContentType;
}
public void setFiledataContentType(String[] filedataContentType) {
this .FiledataContentType = filedataContentType;
}
public String getUploadType() {
return uploadType;
}
public void setUploadType(String uploadType) {
this .uploadType = uploadType;
}
其中,操作数据库部分的代码跟这个例子无关,可以省去。
第五步:要用到的其他类的代码(PS:这部分代码来自互联网)
1:FileUpload.java用于生成缩略图、添加水印、生成无重复的文件名
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.imageio.ImageIO;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class FileUpload {
private static final int BUFFER_SIZE = 16 * 1024;
private static final String WATER_TEXT = "文字水印 ";
private static final String WATER_IMG_NAME = "logo.png ";
/*生成无重复文件名*/
public static String getFileName(String name){
SimpleDateFormat df =new SimpleDateFormat("yyyyMMddHHmmss ");
Date date = new Date();
String filename=null ;
if (!"".equals(name) && name != null ){
filename=df.format(date) + RandomNum.random2() + name.substring(name.lastIndexOf(". "), name.length());
}
System.out.println("filename is: "+filename);
return filename;
}
/*上传文件*/
public static void copy(File src, File dst) {
try {
InputStream in = null ;
OutputStream out = null ;
try {
in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
out = new BufferedOutputStream(new FileOutputStream(dst), BUFFER_SIZE);
byte [] buffer = new byte [BUFFER_SIZE];
while (in.read(buffer) > 0) {
out.write(buffer);
}
} finally {
if (null != in) {
in.close();
}
if (null != out) {
out.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*生成缩略图*/
public static String scaleImage(String fromFileStr, String saveToFileStr, int formatWideth, int formatHeight) throws Exception {
ScaleImage is = new ScaleImage();
try {
is.saveImageAsJpg(fromFileStr, saveToFileStr, formatWideth, formatHeight);
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "error ";
}
return "ok ";
}
/**
* 添加文字水印
*
* @return
* @throws Exception
* @throws Exception
*/
public static void watermark(File img) throws Exception {
System.out.println("[watermark file name]-- " + img.getPath());
try {
if (!img.exists()) {
throw new IllegalArgumentException("file not found! ");
}
System.out.println("[watermark][img]-- " + img);
// 创建一个FileInputStream对象从源图片获取数据流
FileInputStream sFile = new FileInputStream(img);
// 创建一个Image对象并以源图片数据流填充
Image src = ImageIO.read(sFile);
// 得到源图宽
int width = src.getWidth(null );
// 得到源图长
int height = src.getHeight(null );
// 创建一个BufferedImage来作为图像操作容器
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建一个绘图环境来进行绘制图象
Graphics2D g = image.createGraphics();
// 将原图像数据流载入这个BufferedImage
System.out.println("width: " + width + " height: " + height);
g.drawImage(src, 0, 0, width, height, null );
// 设定文本字体
g.setFont(new Font("宋体 ", Font.BOLD, 28));
String rand = WATER_TEXT;
// 设定文本颜色
g.setColor(Color.blue);
// 设置透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
// 向BufferedImage写入文本字符,水印在图片上的坐标
g.drawString(rand, width - (width - 20), height - (height - 60));
// 使更改生效
g.dispose();
// 创建输出文件流
FileOutputStream outi = new FileOutputStream(img);
// 创建JPEG编码对象
JPEGImageEncoder encodera = JPEGCodec.createJPEGEncoder(outi);
// 对这个BufferedImage (image)进行JPEG编码
encodera.encode(image);
// 关闭输出文件流
outi.close();
sFile.close();
} catch (IOException e) {
e.printStackTrace();
throw new Exception(e);
}
}
/**
* 添加图片水印
*
*/
public static void imageWaterMark(File imgFile, String waterFilePath) throws Exception {
try {
// 目标文件
Image src = ImageIO.read(imgFile);
int wideth = src.getWidth(null );
int height = src.getHeight(null );
BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.drawImage(src, 0, 0, wideth, height, null );
// 水印文件 路径
String waterImgPath = waterFilePath + WATER_IMG_NAME;
System.out.println("waterImgPath-- " + waterImgPath);
File waterFile = new File(waterImgPath);
Image waterImg = ImageIO.read(waterFile);
int w_wideth = waterImg.getWidth(null );
int w_height = waterImg.getHeight(null );
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
g.drawImage(waterImg, (wideth - w_wideth) / 2, (height - w_height) / 2, w_wideth, w_height, null );
// 水印文件结束
g.dispose();
FileOutputStream out = new FileOutputStream(imgFile);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2:RandomNum.java用于生成无重复随机数
import java.util.Random;
public class RandomNum {
public static int [] random1() {
Random r = new Random();
int temp1, temp2;
int send[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
int len = send.length;
int returnValue[] = new int [22];
for (int i = 0; i < 22; i++) {
temp1 = Math.abs(r.nextInt()) % len;
returnValue[i] = send[temp1];
temp2 = send[temp1];
send[temp1] = send[len - 1];
send[len - 1] = temp2;
len--;
}
return returnValue;
}
public static int [] random2() {
int send[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
int temp1, temp2, temp3;
Random r = new Random();
for (int i = 0; i < send.length; i++){// 随机交换send.length次
temp1 = Math.abs(r.nextInt()) % (send.length - 1); // 随机产生一个位置
temp2 = Math.abs(r.nextInt()) % (send.length - 1); // 随机产生另一个位置
if (temp1 != temp2) {
temp3 = send[temp1];
send[temp1] = send[temp2];
send[temp2] = temp3;
}
}
return send;
}
}
本文链接地址: http://imleeo.com/java/struts2-flashfileupload-fileupload-and-generate-thumbnails-and-add-watermarks.html