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();
}
參考鏈接
2. Android Bitmap 和 ByteArray的互相轉換