最近参与了一个互联网电子商务项目,需要做图像上传。
要求:对图片在本地预览、打水印、固定大小显示、让用户自己在图片中选取一块出来作为网站的会员头像。
上司给出的解决方案:想办法在客户端用js脚本完成图片切割。
我当初就一口回绝了,除了特殊情况下,基本没有项目会采用js经行文件的读写的,特别是写文件,这会让客户机承受多大的风险吖。万一人家写的是一大堆的病毒呢?
在我的坚持下,还是采用了我的思路:
1.在前台生成本地图片的预览。
2.用js对图片进行缩放显示、打水印。
3.当用户选取图片当中的一部分时,记录选取框大小以及坐标。
4.当用户点击保存时,将图片上传至服务器,同时将缩放比例或者缩放后图片的大小传给后台,并且将选取框的大小和坐标也传给后台。
5.在后台使用ImageIO对图片进行缩放,缩放后再裁减。
简要代码:
完整源代码下载地址:http://download.csdn.net/download/it491328322/4391944
(建议使用firefox测试,原因:源码内的jquery插件,某些IE版本不支持,特别是打过升级包的IE。)
js代码:
/**
* 图片裁剪过程中调用方法
*/
function preview(img, selection)
{
var scaleX = 180 / (selection.width || 1);
var scaleY = 180 / (selection.height || 1);
$('#ferret + div > img').css({
width: Math.round(scaleX * 300) + 'px',
height: Math.round(scaleY * 300) + 'px',
marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px',
marginTop: '-' + Math.round(scaleY * selection.y1) + 'px'
});
}
/**
* 图片裁剪完调用方法
*/
function getCss(img, selection){
createImg(selection.width,selection.height,img,selection.x1,selection.y1);
}
/**
* 生成剪裁后的图片预览
*/
function createImg(width,height,img,startX,startY){
$("#cutImg").remove();
$("<div id='cutImg'></div>").css("width", width + "px").css("height", height + "px")
.css("overflow","hidden").css("display", "block").appendTo($('#tempDiv'));
$(img).clone(true).appendTo($("#cutImg"));
$("#cutImg").get(0).scrollLeft = startX;
$("#cutImg").get(0).scrollTop = startY;
$("#scaleWidth").val(img.width);
$("#scaleHeight").val(img.height);
$("#cutWidth").val(width);
$("#cutHeight").val(height);
$("#cutX").val(startX);
$("#cutY").val(startY);
}
/**
* aspectRatio 选择框的长宽比例
* onSelectChange 选择框改变时的回调函数
* onSelectEnd 选择框移动后的回调函数
*/
$(window).load(function () {
$('#ferret').imgAreaSelect({ selectionOpacity: 0.1
, borderWidth: 1,//aspectRatio:'1:1',
onSelectChange: preview ,onSelectEnd: getCss
});});
/**
* maxWidth 最大宽度
* maxHeight 最大高度
* minWidth 最小宽度
* minHeight 最小高度
* handles 选择框周围是否出现移动点
* x1 选择框的起始坐标 X
* y1 选择框的起始坐标 Y
* x2 选择框的结束坐标 X
* y2 选择框的结束坐标 Y
*/
$(document).ready(function () {
$('#ferret').imgAreaSelect(
{
x1: 80,
y1: 30,
x2: 210,
y2: 160
});
createImg(130, 130, $('#ferret').get(0), 80, 30);
});
/**
* 切换图片时生成预览效果
*/
function chImgSrc(){
var myfile=document.getElementById("face");
var img=document.getElementById("ferret");
img.src = getFullPath(myfile);
createImg(130, 130, $('#ferret').get(0), 80, 30);
}
function getFullPath(obj) {
if (obj) {
//IE
if (window.navigator.userAgent.indexOf("MSIE") >= 1) {
obj.select();
obj.blur();
// IE下取得图片的本地路径
return document.selection.createRange().text;
}
//firefox
else if (window.navigator.userAgent.indexOf("Firefox") >= 1) {
if (obj.files) {
// Firefox下取得的是图片的数据
var value = "";
try{
value = window.URL.createObjectURL(obj.files[0]);
}catch(e){
value = obj.files[0].getAsDataURL();
}
return value;
}
}
return obj.value;
}
}
html代码:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<HTML>
<HEAD>
<TITLE> 图片剪裁 </TITLE>
<link rel="stylesheet" type="text/css" href="css/imgareaselect-default.css" />
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.imgareaselect.js"></script>
<script type="text/javascript" src="js/imageCut.js"></script>
</HEAD>
<BODY>
<form action="upload!regist.action" method="post" enctype="multipart/form-data" >
<div id="localImag" style="float:left;width:350px;">
<img src="img/a.jpg" id="ferret" name="ferret" width="300px" height="300px"/>
</div>
<div style="margin-top:50px;float:left;" id="tempDiv"></div>
<div style="clear:both;"></div>
姓名:<input id="username" name="username" type="text">
玉照:<input type=file id="face" name="face" οnchange="chImgSrc();" > <br>
<input type="hidden" id="scaleWidth" name="scaleWidth">
<input type="hidden" id="scaleHeight" name="scaleHeight">
<input type="hidden" id="cutWidth" name="cutWidth">
<input type="hidden" id="cutHeight" name="cutHeight">
<input type="hidden" id="cutX" name="cutX">
<input type="hidden" id="cutY" name="cutY">
<input type=submit value="提交">
</form>
</BODY>
</HTML>
java代码:
package com.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.imagecut.ImageCut;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private String username; //用户名
private File face; //文件信息
private String faceFileName; //原始文件名
private String faceContentType; //上传类型
private int scaleWidth = 300;
private int scaleHeight = 300;
private int cutWidth;
private int cutHeight;
private int cutX;
private int cutY;
//员工注册处理上传,拦截器帮我们上传了,只要我们复制到我们指定目录
public String regist() throws Exception {
//读
InputStream is = new FileInputStream(face);
//虚拟转真实路径
String path = ServletActionContext.getServletContext().getRealPath("/upload");
//写
OutputStream os = new FileOutputStream(path+"/"+faceFileName);
byte[] b = new byte[1024];
int size = is.read(b);
while (size>0){
os.write(b,0,size);
size = is.read(b);
}
os.close();
is.close();
ImageCut.cutImage(path + "/" + faceFileName, scaleWidth, scaleHeight, cutX, cutY, cutWidth, cutHeight);
return null;
}
public void setUsername(String username) {
this.username = username;
}
public void setFace(File face) {
this.face = face;
}
public void setFaceFileName(String faceFileName) {
this.faceFileName = faceFileName;
}
public void setFaceContentType(String faceContentType) {
this.faceContentType = faceContentType;
}
public int getScaleWidth() {
return scaleWidth;
}
public void setScaleWidth(int scaleWidth) {
this.scaleWidth = scaleWidth;
}
public int getScaleHeight() {
return scaleHeight;
}
public void setScaleHeight(int scaleHeight) {
this.scaleHeight = scaleHeight;
}
public int getCutWidth() {
return cutWidth;
}
public void setCutWidth(int cutWidth) {
this.cutWidth = cutWidth;
}
public int getCutHeight() {
return cutHeight;
}
public void setCutHeight(int cutHeight) {
this.cutHeight = cutHeight;
}
public int getCutX() {
return cutX;
}
public void setCutX(int cutX) {
this.cutX = cutX;
}
public int getCutY() {
return cutY;
}
public void setCutY(int cutY) {
this.cutY = cutY;
}
public String getUsername() {
return username;
}
public File getFace() {
return face;
}
public String getFaceFileName() {
return faceFileName;
}
public String getFaceContentType() {
return faceContentType;
}
}
package com.imagecut;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageCut {
/**
* @param args
*/
public static void main(String[] args) {
try {
ImageCut.cutImage("D:\\app_work\\eclipse_work\\myeclipse6.0.1_workspace\\chenwrite\\WebRoot\\imageCut\\img\\a.jpg", 300,300,70,20, 150, 150);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 生成缩放后的图片和剪裁后的图片
* @param srcPath 原图片的路径
* @param scale 缩放比例
* @param startX 剪裁框的起始坐标 X
* @param startY 剪裁框的起始坐标 Y
* @param width 剪裁后的图片宽度
* @param height 剪裁后的图片高度
* @throws IOException IOException
*/
public static void cutImage(String srcPath, double scale, int startX, int startY, int width, int height) throws IOException {
File srcFile = new File(srcPath);
BufferedImage image = ImageIO.read(srcFile);
int srcWidth = image.getWidth(null);
int srcHeight = image.getHeight(null);
cutImage(srcPath, (int)(srcWidth * scale), (int)(srcHeight * scale), startX, startY, width, height);
}
/**
* 生成缩放后的图片和剪裁后的图片
* @param srcPath 原图片的路径
* @param scaleWidth 缩放后的图片宽度度
* @param scaleHeight 缩放后的图片高度
* @param startX 剪裁框的起始坐标 X
* @param startY 剪裁框的起始坐标 Y
* @param width 剪裁后的图片宽度
* @param height 剪裁后的图片高度
* @throws IOException IOException
*/
public static void cutImage(String srcPath, int scaleWidth, int scaleHeight, int startX, int startY, int width, int height) throws IOException {
File srcFile = new File(srcPath);
BufferedImage image = ImageIO.read(srcFile);
BufferedImage newImage = new BufferedImage(scaleWidth, scaleHeight, BufferedImage.TYPE_INT_RGB);
newImage.getGraphics().drawImage(image.getScaledInstance(scaleWidth, scaleHeight, Image.SCALE_SMOOTH), 0, 0, null);
//保存缩放后的图片
String fileName = srcFile.getName().substring(0,srcFile.getName().lastIndexOf("."));
String fileSufix = srcFile.getName().substring(srcFile.getName().lastIndexOf(".") + 1);
File scaleFile = new File(srcFile.getParent(), fileName + "_scale" + "." + fileSufix);
ImageIO.write(newImage, fileSufix, scaleFile);
//保存裁剪后的图片
File scaleCutFile = new File(srcFile.getParent(), fileName + "_scale_cut" + "." + fileSufix);
ImageIO.write(newImage.getSubimage(startX, startY, width, height), fileSufix, scaleCutFile);
}
}