頭像上傳java_JAVA + js 實現 頭像上傳及裁剪功能

題記

我想大家對頭像上傳功能在陌生不過了把,每個人都應該用過,當然,從不更改頭像的大俠除外,寫到這里,我突然想到我的CSDN用戶也沒有頭像,於是,我到設置里面准備去看看CSDN的頭像上傳功能是怎樣的,可是我弄了半天都沒搞定,提示說高版本瀏覽器不支持預覽,難道只有IE6才支持?難得吐槽一下,不知道是我人品問題還是沒用對。如圖:

6225326e75f133c85c926cedb0b43f1c.jpe

go

准備工作

好了,廢話不多說了,一般常用的頭像上傳有兩種(據我所知):

普通的文件上傳:

普通文件上傳莫非就是,給你一個選擇文件選擇按鈕,你選擇好文件后,剩下的事情你就不管了,后台會把你上傳的圖片按一定的比例縮放,或者無任何處理,或其他操作,這種方式的好處壞處顯而易見,前后台的實現相對來說比較簡單,可是用戶體驗就不是這么滿意了,我以前也遇到過這種,不但自己需要找到大概合適大小比例的圖片,有事還得自己修改裁剪,然后再傳上去,最后結果並不會讓我滿意,我不得不重新在去做一遍這些繁瑣的操作!

帶預覽裁剪功能的上傳:

現在很多用戶體驗還不錯的網站或軟件都采用這種方法,最常用的實現就是用的flash,用戶上傳一張圖片,馬上就可以自己選取需要的部分,而且還帶有及時的預覽效果,體驗非常不錯。

步入正題,最近項目需要,有個地方需要用戶上傳頭像,本來按照產品設計,直接一個選擇框,用戶選擇圖片后上傳就搞定!這種方法不說用戶,就連我開發人員都覺得真心難用,於是我決定弄一個可以預覽裁剪上傳頭像的功能,下面是用到的一款js的圖片裁剪插件,性能還算行幾乎兼容所有的瀏覽器。

實現原理

當我沒接觸到這個功能之前,以為這有多神秘多神秘,其實就是兩個原圖的img標簽,其中一個是讓你選擇預覽范圍,一個讓你看到你選擇后的效果,利用Draggable和Resizable特性在原圖上創建出一個選擇框,然后再按照你選擇的范圍按照一定的比例和算法讓效果圖那個img只顯示你選擇的那一部分,最后把你最后選擇的范圍坐標以及大小傳給后台,后台按照這個范圍裁剪相應的圖片即可!

具體用法

首先引入相應的js/css文件

然后寫入一個image標簽,

flowers.jpg

最后給img標簽添加可裁剪功能

jQuery(function($) {

$('#target').Jcrop();

});

效果如下:

go

b05b821f61846a844dc811e80272c0fb.jpe

如果想預覽你選擇后的圖片,再寫入一個img標簽

flowers.jpg

代碼改成

$(function(){

$('#target').Jcrop({

onChange: showPreview,

onSelect: showPreview,

aspectRatio: 1

});

});

當選擇框改變,將會執行下面的函數

function showPreview(coords)

{

var rx = 100 / coords.w;

var ry = 100 / coords.h;

$('#preview').css({

width: Math.round(rx * 300) + 'px',

height: Math.round(ry * 300) + 'px',

marginLeft: '-' + Math.round(rx * coords.x) + 'px',

marginTop: '-' + Math.round(ry * coords.y) + 'px'

});

}

這樣,id為preview將只會顯示你選擇的范圍的圖片

dc51c35ba9f307040ec6a2b49c6ae027.jpe

go

與JAVA后台結合

前台實現其實很簡單,Jcrop下載下來已經有完整的Demo可以運行,用法也很簡單,最麻煩的就是后台了,我們可以通過回調函數showPreview得到選擇框的x,y,width,height,然后傳到后台按照坐標裁剪圖片即可,官方是這種說的,可問題來了,我們得到的x,y,w,h只是相對於被縮小后的id為target的img標簽的,假設一張1024x768的圖,target的大小肯定是固定的,圖中為504x374,所以得到的x,y,h,w是基於此比例來的,如果傳到后台你用這個坐標來裁剪原圖,肯定有問題,這個問題糾結了我很久,我想過通過一定的比例算法來計算實際的x,y是多少,但一直都沒找到傳到后台的坐標和實際要裁剪的坐標有什么關系,我網上查了很多人說也是直接通過傳過來的x,y等參數直接生成新的圖片,可生成的圖片完全和我選擇的不一樣,我也想過把圖片先壓縮成target一樣大,然后xy就正確了,但是看到preview里的效果圖了嗎,那是在原圖上選擇后的效果,后來我發現preview不就是我要的效果嗎,於是打開firebug研究了一下

8aa99b3cb66fb42133fcf9592c93b2a9.jpe

go

通過樣式我們看到,圖片被放大到758x561,並且左外邊距和上外邊距分別設置成了-529和-261,於是我明白了,后台按照一樣的思路不就行了嗎?先把圖片轉成758x561,然后在按照x:528 y:261的坐標裁剪一定的大小,不就是最后要的圖片么,

后台用到的java代碼方法

/**

* 縮放后裁剪圖片方法

* @param srcImageFile 源文件

* @param x x坐標

* @param y y坐標

* @param destWidth 最終生成的圖片寬

* @param destHeight 最終生成的圖片高

* @param finalWidth 縮放寬度

* @param finalHeight 縮放高度

*/

public static void abscut(String srcImageFile, int x, int y, int destWidth,

int destHeight,int finalWidth,int finalHeight) {

try {

Image img;

ImageFilter cropFilter;

// 讀取源圖像

BufferedImage bi = ImageIO.read(new File(srcImageFile));

int srcWidth = bi.getWidth(); // 源圖寬度

int srcHeight = bi.getHeight(); // 源圖高度

if (srcWidth >= destWidth && srcHeight >= destHeight) {

Image image = bi.getScaledInstance(finalWidth, finalHeight,Image.SCALE_DEFAULT);//獲取縮放后的圖片大小

cropFilter = new CropImageFilter(x, y, destWidth, destHeight);

img = Toolkit.getDefaultToolkit().createImage(

new FilteredImageSource(image.getSource(), cropFilter));

BufferedImage tag = new BufferedImage(destWidth, destHeight,

BufferedImage.TYPE_INT_RGB);

Graphics g = tag.getGraphics();

g.drawImage(img, 0, 0, null); // 繪制截取后的圖

g.dispose();

// 輸出為文件

ImageIO.write(tag, "JPEG", new File(srcImageFile));

}

} catch (Exception e) {

e.printStackTrace();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值