Android開發實踐:自己動手編寫圖片剪裁應用(3)

來源:互聯網
上載者:User

標籤:rotate   crop   

前面兩篇文章分別介紹了我編寫的開源項目ImageCropper庫,以及如何調用系統的圖片剪裁模組,本文則繼續分析一下開發Android圖片剪裁應用中需要用到的Bitmap操作。


在Android系統中,對圖片的操作主要是通過Bitmap類和Matrix類來完成,本文就介紹一片剪裁應用中對Bitmap的一些操作,包括:開啟、儲存、剪裁、旋轉等,我已經將這些操作都封裝到了一個BitmapHelper.java類中,放到GitHub上了(點擊這裡),大家可以方便地整合到自己的項目中。


  1. 開啟圖片


圖片的開啟主要是把各種格式的圖片轉換為Bitmap對象,Android通過BitmapFactory類提供了一系列的靜態方法來協助完成這個操作,如下所示:


public class BitmapFactory {    public static Bitmap decodeFile(String pathName, Options opts);    public static Bitmap decodeFile(String pathName);    public static Bitmap decodeResourceStream(Resources res, TypedValue value,            InputStream is, Rect pad, Options opts) ;    public static Bitmap decodeResource(Resources res, int id, Options opts) ;    public static Bitmap decodeResource(Resources res, int id);    public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts);    public static Bitmap decodeByteArray(byte[] data, int offset, int length);    public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts);    public static Bitmap decodeStream(InputStream is) ;    public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts);    public static Bitmap decodeFileDescriptor(FileDescriptor fd) ;}

通過這些靜態方法,我們可以方便地從檔案、資源、位元組流等各種途徑開啟圖片,產生Bitmap對象。下面給出一個從檔案中開啟圖片的函數封裝:


    public static Bitmap load( String filepath ) {        Bitmap bitmap = null;        try {            FileInputStream fin = new FileInputStream(filepath);            bitmap = BitmapFactory.decodeStream(fin);            fin.close();        }        catch (FileNotFoundException e) {                    }         catch (IOException e) {                        }        return bitmap;    }


2. 儲存圖片


圖片的儲存則主要通過Bitmap的compress方法,該方法的原型如下:


/**  * Write a compressed version of the bitmap to the specified outputstream.      * @param format   The format of the compressed image  * @param quality  Hint to the compressor, 0-100. 0 meaning compress for  *                 small size, 100 meaning compress for max quality. Some  *                 formats, like PNG which is lossless, will ignore the  *                 quality setting  * @param stream   The outputstream to write the compressed data.  * @return true if successfully compressed to the specified stream.  */public boolean compress(CompressFormat format, int quality, OutputStream stream)

第一個參數是圖片格式,只有JPEG、PNG和WEBP三種,第二個參數是壓縮品質(0~100),數值越大圖片資訊損失越小,第三個參數則是檔案流對象。


同樣,這裡給出一個儲存圖片的函數封裝:


public static void save( Bitmap bitmap, String filepath ) {    try {        FileOutputStream fos = new FileOutputStream(filepath);        bitmap.compress(CompressFormat.JPEG, 100, fos);                      bitmap.recycle();                    fos.close();                 }     catch (FileNotFoundException e) {                }      catch (IOException e) {                       }    }


3. 剪裁圖片


Android中剪裁圖片主要有2種方法,一種通過Bitmap的createBitmap方法來產生剪裁的圖片,另一種則是通過Canvas對象來“繪製”新的圖片,這裡先給出代碼,再分析:


public static Bitmap crop( Bitmap bitmap, Rect cropRect ) {    return Bitmap.createBitmap(bitmap,cropRect.left,cropRect.top,cropRect.width(),cropRect.height());}    public static Bitmap cropWithCanvas( Bitmap bitmap, Rect cropRect ) {    Rect destRect = new Rect(0,0,cropRect.width(),cropRect.height());    Bitmap cropped = Bitmap.createBitmap(cropRect.width(),cropRect.height(),Bitmap.Config.RGB_565);    Canvas canvas = new Canvas(cropped);            canvas.drawBitmap(bitmap,cropRect,destRect,null);    return cropped;}


其實第一種方法內部實現也是利用了Canvas對象來“繪製”新的圖片的,Canvas對象通過一個Bitmap對象來構建,該Bitmap即為“畫布”,drawBitmap則是將源bitmap對象“畫”到“畫布”之中,這樣就實現了資料的搬移,實現了圖片的剪裁。


4. 旋轉圖片


Android中旋轉圖片同樣是通過Bitmap的createBitmap方法來產生旋轉後的圖片,不過圖片的旋轉需要藉助Matrix對象來協助完成,代碼如下:


public static Bitmap rotate( Bitmap bitmap, int degrees  ) {    Matrix matrix = new Matrix();    matrix.postRotate(degrees);                return Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);}


當然,圖片的旋轉也是可以通過Canvas來“繪製”,由於圖片旋轉會導致邊界座標發生變化,所以需要以圖片中心點座標為中心來旋轉,具體實現見如下代碼:


public static Bitmap rotateWithCanvas( Bitmap bitmap, int degrees  ) {            int destWidth,destHeight;            float centerX = bitmap.getWidth()/2;    float centerY = bitmap.getHeight()/2;                    // We want to do the rotation at origin, but since the bounding    // rectangle will be changed after rotation, so the delta values    // are based on old & new width/height respectively.    Matrix matrix = new Matrix();            matrix.preTranslate(-centerX,-centerY);    matrix.postRotate(degrees);            if( degrees/90%2 == 0 ) {         destWidth  = bitmap.getWidth();        destHeight = bitmap.getHeight();        matrix.postTranslate(centerX,centerY);    }            else {                    destWidth  = bitmap.getHeight();        destHeight = bitmap.getWidth();        matrix.postTranslate(centerY,centerX);                }    Bitmap cropped = Bitmap.createBitmap(destWidth,destHeight,Bitmap.Config.RGB_565);    Canvas canvas = new Canvas(cropped);           canvas.drawBitmap(bitmap, matrix, null);    return cropped;}


5. 小結


關於Bitmap的相關操作就介紹到這裡了,更多的程式碼範例和實現可以參考我的開源項目ImageCropper,

該項目的GitHub地址:https://github.com/Jhuster/ImageCropper,有任何疑問歡迎留言討論或者來信[email protected]交流。


本文出自 “對影成三人” 部落格,請務必保留此出處http://ticktick.blog.51cto.com/823160/1604074

Android開發實踐:自己動手編寫圖片剪裁應用(3)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.