Android Bitmap常見用法

1. 攝像頭byte[]數據轉爲bitmap

正確方法

public static Bitmap saveBGRA8888ByteToBitmap(byte[] data, int width, int height) {
    byte[] bgraData = new byte[width*height*4];
    System.arraycopy(data, 0, bgraData, 0, width*height*4);

    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    ByteBuffer buf = ByteBuffer.wrap(bgraData);
    bitmap.copyPixelsFromBuffer(buf);

    return bitmap;
}

這種方法在攝像頭會出現getwidth NPE應該byte[]不包含這些數據

byte[] b = getIntent().getByteArrayExtra("bitmap");  
Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);

2. bitmap轉爲byte[]數據

int bytes = bmp.getByteCount();

ByteBuffer buf = ByteBuffer.allocate(bytes);
bmp.copyPixelsToBuffer(buf);

byte[] byteArray = buf.array();

3. bitmap保存爲圖片

/*
 * 保存bitmap到圖片,PNG可以選擇其他格式JPE PNG
 * @param bitmap原圖
 * @param savaPath保存文件的路徑
 */
public static void saveBitmapToJpg(Bitmap bitmap, String savePath) {
    File file=new File(savePath);
    try {
        FileOutputStream fos = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
    
@frameworks/base/graphics/java/android/graphics/Bitmap.java
public enum CompressFormat {
    JPEG    (0),
    PNG     (1),
    WEBP    (2);
    
    CompressFormat(int nativeInt) {
        this.nativeInt = nativeInt;
    }
    final int nativeInt;
}
    

4. byte[]直接保存爲圖片

/*
 *把BGRA格式的byte[]數據保存到圖片
 *@param data: 攝像頭傳過來的圖像數據
 *@param width: 圖片的寬度
 *@param height: 圖片的高度
 *@param savaPath保存文件的路徑
 */
public static void saveBGRA8888ToPicture(byte[] data, int width, int height, String savePath) {
    byte[] bgraData = new byte[width*height*4];
    System.arraycopy(data, 0, bgraData, 0, width*height*4);

    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    ByteBuffer buf = ByteBuffer.wrap(bgraData);
    bitmap.copyPixelsFromBuffer(buf);

    File file=new File(savePath);
    if(file.exists()){
        file.delete();
    }
    try {
        FileOutputStream fos = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    bitmap.recycle();
}

//適用於yuv格式的byte[]保存
public static boolean saveYuvByteToJpegFile(byte[] bytes, int width, int height, String oldName){
    FileOutputStream fileOutputStream = null;
    ByteArrayOutputStream byteArrayOutputStream = null;
    Bitmap bitmap = null;
    String filePath = EXTERNAL_FILES_PATH + "/sensetime" + "/" + oldName + ".jpeg";
    File fileDir = new File(EXTERNAL_FILES_PATH + "/sensetime");
    if(!fileDir.exists() && !fileDir.mkdir()){
        return false;
    }
    File file = new File(filePath);
    try{
        YuvImage yuvImage = new YuvImage(bytes, ImageFormat.NV21, width, height, null);
        byteArrayOutputStream = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, byteArrayOutputStream);
        bitmap = BitmapFactory.decodeByteArray(byteArrayOutputStream.toByteArray(), 0, byteArrayOutputStream.size());
        if(!file.exists() && !file.createNewFile()) return false;
        fileOutputStream = new FileOutputStream(file);
        return bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
    }catch (Exception e){
        Log.e(TAG, e.toString());
    }finally {
        try{
            if(fileOutputStream != null){
                fileOutputStream.flush();
                fileOutputStream.close();
            }
            if(byteArrayOutputStream != null){
                byteArrayOutputStream.flush();
                byteArrayOutputStream.close();
            }
            if(bitmap != null){
                bitmap.recycle();
                bitmap = null;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    return false;
}



5. 從圖片得到Bitmap

會通過inSampleSize的值來壓縮分辨率

public static Bitmap getImageResource(String imagePath){
    Bitmap bitmap = null;
    try{
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        bitmap = BitmapFactory.decodeFile(imagePath, options);
        int previewWidth = options.outWidth;
        int previewHeight = options.outHeight;
        options.inJustDecodeBounds = false;
        if(previewWidth > 2560 || previewHeight > 2560) options.inSampleSize = 8;
        else if(previewWidth > 1280 || previewHeight > 1280) options.inSampleSize = 4;
        else if(previewWidth > 640 || previewHeight > 640) options.inSampleSize = 2;
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        bitmap = BitmapFactory.decodeFile(imagePath, options);
    }catch (Exception e){
        e.printStackTrace();
    }
    return bitmap;
}


6. bitmap的裁剪

//基本裁剪接口 
public static Bitmap cropBitmap(Bitmap bitmap, int x, int y, int width, int height) {
    return Bitmap.createBitmap(bitmap, x, y, width, height);
}


/*
 *@param bitmap: 原圖
 *@param x,y: 截取框第一個點的的xy座標
 *@param width: 截取bitmap的寬度
 *@param height: 截取bitmap的高度
 *@param newWidth newHeight 按上面參數截取後在壓縮到newWidth newHeight尺寸
 */
public static Bitmap cropBitmap(Bitmap bitmap, int x, int y, int width, int height, int newWidth , int newHeight) {
    Matrix matrix = new Matrix();

    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    Log.e(TAG, "cropBitmap scaleWidth: " + scaleWidth + "  scaleHeight: " + scaleHeight);

    matrix.postScale(scaleWidth, scaleHeight);
    return Bitmap.createBitmap(bitmap, x, y, width, height, matrix, true );
}

7. 從resource得到bitmap

bgra.jpg是width*heihgt 1280×720圖片,在車技上得到bitmap的高度上正確的,而在pixel手機上爲:
bitmap width: 3360 height:1890被拉伸了,要注意這種情況

UseBitmap(this, imageView , R.drawable.bgra);

// 1.從資源中獲取Bitmap
public void UseBitmap(Context context, ImageView imageView, int drawableId) {
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), drawableId);
    Log.d(TAG, "bitmap width: " + bitmap.getWidth() + " height:" + bitmap.getHeight());
    Bitmap mbitmap = Bitmap.createBitmap(bitmap, 0 , 0 ,700 ,700);
    Bitmap mmbitmap = Bitmap.createBitmap(mbitmap, 0 , 0 ,300 ,300);
    Bitmap mmmbitmap = Bitmap.createBitmap(mmbitmap, 0 , 0 ,200 ,100);
    imageView.setImageBitmap(mmmbitmap);
    bitmap.recycle();
    //mbitmap.recycle();
}

參考鏈接

1. 開源一個 Android 圖片壓縮框架

2. Android Bitmap 和 ByteArray的互相轉換

3. Android Bitmap最全面詳解


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章