Jcropを使います.jsとjQuery.form.jsは、ImageIOなどで顔のアップロード・ズームやカットを行います
14588 ワード
まず、JavaコードにImageReaderを取得するIteratorが付いています
最初のステップはjQueryでform.jsのajaxSubmit()はアップロードした元のピクチャを提出し、ピクチャをスケーリングして等比例サイズのピクチャを返し、返されるピクチャの最大サイズを1000 px X 500 pxに制限する
Javaコアコードは次のとおりです.
返されるパラメータには、ズーム後の画像の長さと幅の情報があり、フロントjsで取得され、Jcropを初期化します.
フロントコアコード(ajaxSubmit()および成功後のトリガ):
Jcrop関連初期化のjsコード:
ステップ2:
ユーザはトリミングボックスをドラッグして終了し、トリミングボタンをクリックした後、開始点の横縦座標とトリミング領域の幅の高さの4つのパラメータをアップロードします.
今回のプロセスではパラメータのみがアップロードされ、画像はアップロードされず、バックグラウンドではパラメータに基づいて前のステップでスケールした画像を再び切り取り、スケールします.
jsコードは省略し、バックグラウンドJavaコアコードは以下の通りである.
Controlでの主な呼び出し方法:
HTML 5のcanvasやflashを利用して切り取ることについても考えていますが、互換性を考えると、まずそうしましょう.
関連資源:http://download.csdn.net/detail/lgh06/8343359ポイントフリー
プレビュー効果:
本文はブロガーのオリジナル文章で、ブロガーの許可を得ずに転載してはならない.
/**
* 。
* ImageReader Iterator, ImageReader 。
* :postFix - .( "jpeg" "tiff") 。
*
* @param postFix
*
* @author
* @return
*/
public Iterator<ImageReader> getImageReadersByFormatName(String postFix) {
switch (postFix) {
case "jpg":
return ImageIO.getImageReadersByFormatName("jpg");
case "jpeg":
return ImageIO.getImageReadersByFormatName("jpeg");
case "gif":
return ImageIO.getImageReadersByFormatName("gif");
case "bmp":
return ImageIO.getImageReadersByFormatName("bmp");
case "png":
return ImageIO.getImageReadersByFormatName("png");
default:
return ImageIO.getImageReadersByFormatName("jpg");
}
}
最初のステップはjQueryでform.jsのajaxSubmit()はアップロードした元のピクチャを提出し、ピクチャをスケーリングして等比例サイズのピクチャを返し、返されるピクチャの最大サイズを1000 px X 500 pxに制限する
Javaコアコードは次のとおりです.
/**
*
* imgFileZoom: ,
*
* @author
* @param postFix
* @param in
* @param out
* @param showHeight
* @param showWidth
* @return
* @throws IOException
* @since Ver 1.1
*/
public Map<String,String> imgFileZoom(String postFix,InputStream in,FileOutputStream out,int showHeight,int showWidth) throws IOException{
//FileInputStream is = null;
ImageInputStream iis = null;
Map<String,String> map = new HashMap<String,String>();
try {
//
//is = new FileInputStream(in);
//
System.out.println(" :" + postFix);
/*
* ImageReader Iterator, ImageReader 。
* :formatName - .( "jpeg" "tiff") 。
*/
Iterator<ImageReader> it = this.getImageReadersByFormatName(postFix);
ImageReader reader = it.next();
//
iis = ImageIO.createImageInputStream(in);
/*
* <p>iis: .true: </p>. ‘ ’。
* , reader 。
*/
reader.setInput(iis, true);
int realWidth = reader.getWidth(0);
int realHeight = reader.getHeight(0);
double ratio = 1.0;
if(realWidth>showWidth){
BigDecimal d1 = new BigDecimal(showWidth);
BigDecimal d2 = new BigDecimal(realWidth);
ratio = d1.divide(d2, 8,BigDecimal.ROUND_HALF_UP).doubleValue();
}else if(realHeight>showHeight){
BigDecimal d1 = new BigDecimal(showHeight);
BigDecimal d2 = new BigDecimal(showHeight);
ratio = d1.divide(d2, 8,BigDecimal.ROUND_HALF_UP).doubleValue();
}else{
ratio = 1.0;
}
BigDecimal ratioDecimal = new BigDecimal(ratio);
BigDecimal realWidthDecimal = new BigDecimal(realWidth);
BigDecimal realHeightDecimal = new BigDecimal(realHeight);
BigDecimal outputWidthDecimal = BigDecimal.ONE;
BigDecimal outputHeightDecimal = BigDecimal.ONE;
outputWidthDecimal = realWidthDecimal.multiply(ratioDecimal);
outputHeightDecimal = realHeightDecimal.multiply(ratioDecimal);
int outputWidth = outputWidthDecimal.intValue();
int outputHeight = outputHeightDecimal.intValue();
//
map.put("outputWidth", String.valueOf(outputWidth));
map.put("outputHeight", String.valueOf(outputHeight));
/*
* ImageReadParam imageIndex ,
* BufferedImage 。
*/
BufferedImage bi = reader.read(0);
/*
*
*/
Image imageSmall = bi.getScaledInstance(outputWidth, outputHeight, Image.SCALE_DEFAULT);
BufferedImage small = new BufferedImage(outputWidth, outputHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = small.getGraphics();
g.drawImage(imageSmall, 0, 0, null); // Image BufferedImage
g.dispose();
//
ImageIO.write(small, postFix, out);
} finally {
if (in != null)
in.close();
if (iis != null)
iis.close();
if (out != null)
out.close();
}
return map;
}
/**
*
* updateZoomTxService: ,
*
* @author
* @param pic
* @param req
* @return
* @since Ver 1.1
*/
public Map<String,Object> uploadZoomTx(MultipartFile pic,String uid,HttpServletRequest req){
// CommonInfo
String pathString = CommonInfo.touxiangPath+"/zoom/";
String fileName = "";
Map<String,Object> map = new HashMap<String,Object>();
//
if (pic.getSize() > 0) {
//user.setImage(pathString + pic.getOriginalFilename());
//
File file = new File(pathString);
if (!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
try {
String ext=pic.getOriginalFilename().substring(pic.getOriginalFilename().lastIndexOf(".")+1,pic.getOriginalFilename().length());
fileName = System.currentTimeMillis()+uid+"."+ext;
//
FileOutputStream fout = new FileOutputStream(pathString + fileName );
map.put("imgInfo",this.imgFileZoom(ext.toLowerCase(),pic.getInputStream(),fout,500,1000));
map.put("imgUrl", fileName);
if(fout!=null)
fout.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return map;
}
返されるパラメータには、ズーム後の画像の長さと幅の情報があり、フロントjsで取得され、Jcropを初期化します.
フロントコアコード(ajaxSubmit()および成功後のトリガ):
$("#uploadTxBtn").click(function(){
var option = {
type: "post",
success : function(data){
zoomPicName = data['imgUrl'];
$("#p_img").attr("src", "../../touxiang/zoom/"+data['imgUrl']);
$("#p_img").show();
$("#preview_block").show();
$("#p_img_preview").attr("src", "../../touxiang/zoom/"+data['imgUrl']);
$("#p_img").width(data['imgInfo']['outputWidth']);
$("#p_img").height(data['imgInfo']['outputHeight']);
$("#uploadZoomTx").height(parseInt(data['imgInfo']['outputHeight'])+150);
caijian();
}
};
$("#uploadZoomTx").ajaxSubmit(option);
});
Jcrop関連初期化のjsコード:
function caijian(){
// Create variables (in this scope) to hold the API and image size
var jcrop_api, boundx, boundy;
$('#p_img').Jcrop({
onChange: updatePreview,
onSelect: updatePreview,
aspectRatio: 1,
setSelect: [0,0,100,100]
},function(){
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
console.log(1111);
console.log(bounds);
// Store the API in the jcrop_api variable
jcrop_api = this;
});
function updatePreview(c)
{
if (parseInt(c.w) > 0)
{
console.log(c);
img_x = c.x;
img_y = c.y;
img_w = c.w;
img_h = c.h;
var rx = 100 / c.w;
var ry = 100 / c.h;
$('#p_img_preview').css({
width: Math.round(rx * boundx) + 'px',
height: Math.round(ry * boundy) + 'px',
marginLeft: '-' + Math.round(rx * c.x) + 'px',
marginTop: '-' + Math.round(ry * c.y) + 'px'
});
}
};
}
ステップ2:
ユーザはトリミングボックスをドラッグして終了し、トリミングボタンをクリックした後、開始点の横縦座標とトリミング領域の幅の高さの4つのパラメータをアップロードします.
今回のプロセスではパラメータのみがアップロードされ、画像はアップロードされず、バックグラウンドではパラメータに基づいて前のステップでスケールした画像を再び切り取り、スケールします.
jsコードは省略し、バックグラウンドJavaコアコードは以下の通りである.
/**
*
* imgFileCut: ,
*
* @author
* @param postFix
* @param in
* @param out
* @param x
* @param y
* @param width
* @param height
* @param showHeight
* @param showWidth
* @throws IOException
* @since Ver 1.1
*/
public void imgFileCut(String postFix,InputStream in,FileOutputStream out,int x,int y,int width,int height) throws IOException{
ImageInputStream iis = null;
try {
/*
* ImageReader Iterator, ImageReader 。
* :formatName - .( "jpeg" "tiff") 。
*/
Iterator<ImageReader> it = getImageReadersByFormatName(postFix);
ImageReader reader = it.next();
//
iis = ImageIO.createImageInputStream(in);
/*
* <p>iis: .true: </p>. ‘ ’。
* , reader 。
*/
reader.setInput(iis, true);
/*
* <p> <p>. Java Image I/O
* 。 ImageReader
* getDefaultReadParam ImageReadParam 。
*/
ImageReadParam param = reader.getDefaultReadParam();
/*
* 。Rectangle , Rectangle
* (x,y)、 。
*/
Rectangle rect = new Rectangle(x, y, width, height);
// BufferedImage, 。
param.setSourceRegion(rect);
/*
* ImageReadParam imageIndex ,
* BufferedImage 。
*/
BufferedImage bi = reader.read(0, param);
/*
*
*/
Image imageSmall = bi.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
BufferedImage small = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
Graphics g = small.getGraphics();
g.drawImage(imageSmall, 0, 0, null); // Image BufferedImage
g.dispose();
//
ImageIO.write(small, postFix, out);
} finally {
if (in != null)
in.close();
if (iis != null)
iis.close();
if (out != null)
out.close();
}
}
public String saveTx(String zoomedImageName, String img_x, String img_y,
String img_w, String img_h) {
String zoomedImagePath = CommonInfo.touxiangPath+"/zoom/"+zoomedImageName;
String finalImagePath = CommonInfo.touxiangPath+zoomedImageName;
File zoomedImagefile = new File(zoomedImagePath);
try {
InputStream in = new FileInputStream(zoomedImagefile);
File finalImage = new File(finalImagePath);
FileOutputStream out = new FileOutputStream(finalImage);
int x = new BigDecimal(img_x).intValue();
int y = new BigDecimal(img_y).intValue();
int w = new BigDecimal(img_w).intValue();
int h = new BigDecimal(img_h).intValue();
String postFix=zoomedImageName.substring(zoomedImageName.lastIndexOf(".")+1,zoomedImageName.length()).toLowerCase();
this.imgFileCut(postFix, in, out, x, y, w, h);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(" ");
return "error";
}
return "success";
}
Controlでの主な呼び出し方法:
/**
*
* updateZoomTx: ,
*
* @author
* @param pic
* @param req
* @return
* @since Ver 1.1
*/
@ResponseBody
@RequestMapping(value = "/uploadZoomTx.do")
public Map<String,Object> updateZoomTx(MultipartFile pic,HttpServletRequest req){
Map<String,Object> map = null;
if(req.getSession()!=null&&req.getSession().getAttribute("curruser")!=null){
String uid = "";
uid = ((User)(req.getSession().getAttribute("curruser"))).getId();
map =userService.uploadZoomTx(pic,uid,req);
}else{
map=new HashMap<String,Object>();
map.put("error","error");
}
return map;
}
/**
*
* saveTx: ,
*
* @author
* @param zoomedImageName
* @param img_x
* @param img_y
* @param img_w
* @param img_h
* @param req
* @return
* @since Ver 1.1
*/
@ResponseBody
@RequestMapping(value = "/saveTx.do")
public String saveTx(String zoomedImageName,String img_x,String img_y,String img_w,String img_h,HttpServletRequest req){
String re =userService.saveTx( zoomedImageName,img_x, img_y, img_w, img_h);
if(req.getSession()!=null&&req.getSession().getAttribute("curruser")!=null){
User user = (User)(req.getSession().getAttribute("curruser"));
user.setImage(zoomedImageName);
userService.saveOrUpdate(user);
return "ok";
}else{
return "error";
}
}
HTML 5のcanvasやflashを利用して切り取ることについても考えていますが、互換性を考えると、まずそうしましょう.
関連資源:http://download.csdn.net/detail/lgh06/8343359ポイントフリー
プレビュー効果:
本文はブロガーのオリジナル文章で、ブロガーの許可を得ずに転載してはならない.