Web端裁剪圖片方法

segmentfault發表於2016-01-10

  由於在Web端,JavaScript不能直接處理本地檔案,因此可以在後臺裁剪圖片,或者利用html5的canvas來處理。

 方法1:傳送到後臺剪下

  步驟1:上傳圖片到後臺,向前端返回圖片URL

  利用input標籤,將檔案傳送到後臺。

<input id="image" type="file" name="image" />

  可以使用jQuery中的ajaxFileUpload方法

     $.ajaxFileUpload(
        {
            url: 'live/apply/uploadImage', //用於檔案上傳的伺服器端請求地址
            type:'post',
            secureuri: false, //一般設定為false
            fileElementId: image, //檔案上傳空間的id屬性  
            dataType: 'json', //返回值型別 一般設定為json
            data:data, //可以傳遞圖片屬性及其他資料
            success: function (data, status)  //伺服器成功響應處理函式
                {
                    //上傳傳成功處理
                },
            error: function (data, status, e)//伺服器響應失敗處理函式
                 {
                    //上傳失敗處理
                 }

  步驟2: 進行裁剪,獲取圖片的座標及長寬等值,傳回後臺

  這裡一般是利用一個移動的div來獲取剪截的動畫效果,目前有多種jquery外掛可以使用,本文使用的是Jcrop外掛,比較簡單方便。

    $("#myPhoto").Jcrop({
        onChange:showPreview,
        onSelect:showPreview,
        aspectRatio:1
    });    
    function showPreview(coords){
        if(parseInt(coords.w){
        //計算預覽區域圖片縮放的比例,通過計算顯示區域的寬度(與高度)與剪裁的寬度(與高度)之比得到
            var rx = $("#preview_box").width() / coords.w; 
            var ry = $("#preview_box").height() / coords.h;
            //通過比例值控制圖片的樣式與顯示
            $("#crop_preview").css({
                width:Math.round(rx * $("#myPhoto").width()) + "px",    //預覽圖片寬度為計算比例值與原圖片寬度的乘積
                height:Math.round(rx * $("#myPhoto").height()) + "px",    //預覽圖片高度為計算比例值與原圖片高度的乘積
                marginLeft:"-" + Math.round(rx * coords.x) + "px",
                marginTop:"-" + Math.round(ry * coords.y) + "px"
            });
            
            $("#X1").val(coords.x);
            $("#Y1").val(coords.y);
            $("#X2").val(coords.x2);
            $("#Y2").val(coords.y2);
            $("#W").val(coords.w);
            $("#H").val(coords.h);
        }
    }
});

  根據上述過程,可以將獲取到的剪截橫縱座標和長寬資料傳送到後臺。

  步驟3:後臺裁剪圖片

  以java程式碼為例

    /*
     * 圖片裁剪通用介面
     * src:圖片位置,dest:圖片儲存位置
     * 若要覆蓋原圖片,只需src == dest即可
     */
    public static void cutImage(String src,String dest,int x,int y,int w,int h) throws IOException{ 
        
           File srcImg =new File(src);
           //獲取字尾名
           String suffix = srcImg.getName().substring(srcImg.getName().lastIndexOf(".") + 1);
           //根據不同的字尾獲取圖片讀取器
           Iterator iterator = ImageIO.getImageReadersBySuffix(suffix); 
           ImageReader reader = (ImageReader)iterator.next(); 
           
           InputStream in=new FileInputStream(src);
           ImageInputStream iis = ImageIO.createImageInputStream(in); 
           
           reader.setInput(iis, true); 
           ImageReadParam param = reader.getDefaultReadParam(); 
          
           //設定裁剪位置
           Rectangle rect = new Rectangle(x, y, w,h);  
           param.setSourceRegion(rect); 
           
           //儲存裁剪後的圖片
           BufferedImage bi = reader.read(0,param);   
           ImageIO.write(bi, suffix, new File(dest));       
    } 

 方法2:Html5的canvas技術

  這個需要瀏覽器支援以下幾個點,並且相容性還沒有進行測試:

  • File API

  • Blob

  • canvas

  步驟1:讀取檔案

  如方法1一樣,需要用input標籤來獲取file,但是JavaScript不能直接操作檔案,因此需要File API來處理。

$('input[type=file]').change(function(){
    var file=this.files[0];
    var reader=new FileReader();
    
    reader.onload=function(){
        // 通過 reader.result 來訪問生成的 DataURL
        var url=reader.result;
        setImageURL(url);
    };
    
    reader.readAsDataURL(file);
});

var image=new Image();
function setImageURL(url){
    image.src=url;
}

  步驟2:獲取裁剪座標

  參照方法1中的步驟2

  步驟3:利用canvas重繪圖片

  首先要設定剪截後的圖片大小相等的canvas。

// 以下四個引數由步驟2獲得
var x,  y, width, height;

var canvas=$('<canvas width="'+width+'" height="'+height+'"></canvas>')[0],
ctx=canvas.getContext('2d');

ctx.drawImage(image,x,y,width,height,0,0,width,height);//重繪
$(document.body).append(canvas);//新增到文件中可以檢視效果

  步驟4:儲存圖片

  我們要獲取 canvas 中圖片的資訊,需要用 toDataURL 轉換成上面用到的 DataURL 。 然後取出其中 base64 資訊,再用 window.atob 轉換成由二進位制字串。但 window.atob 轉換後的結果仍然是字串,直接給 Blob 還是會出錯。所以又要用 Uint8Array 轉換一下。

var data=canvas.toDataURL();

// dataURL 的格式為 “data:image/png;base64,****”,逗號之前都是一些說明性的文字,我們只需要逗號之後的就行了
data=data.split(',')[1];
data=window.atob(data);
var ia = new Uint8Array(data.length);
for (var i = 0; i < data.length; i++) {
    ia[i] = data.charCodeAt(i);
};

// canvas.toDataURL 返回的預設格式就是 image/png
var blob=new Blob([ia], {type:"image/png"});

  步驟5:將blob資料傳送至後臺

  在後臺可以將Blob格式的資料轉換成image儲存。

相關文章