[英]Android: Bitmap compression is causing out of memory problems
我正在嘗試壓縮從圖庫中選取或由相機捕獲的位圖,然后再發送到服務器。 現在,我按照以下步驟進行操作:
1)獲取圖像的路徑。
2)從該路徑獲取位圖。
3)檢查位圖的初始寬度和高度,並將其與最大寬度和高度進行比較,然后使用比例因子調整寬度和高度。
4)使用exif檢查並正確旋轉位圖。
5)最終降低質量以獲得最終的壓縮位圖。
編碼:
private static final float max_width = 1280.0f;
private static final float max_height = 1280.0f;
private static final float max_ratio = max_width/max_height;
private void CompressImage(String path , Bitmap bitmap_original){
//get width and height of original bitmap
int original_width = bitmap_original.getWidth();
int original_height = bitmap_origianl.getHeight();
float original_ratio = (float)width/(float)height;
if(original_height > max_height || original_width > max_width){
//adjust bitmap dimensions
int width = 0;
int height = 0;
if(original_ratio<max_ratio){
width= (int)((max_height/original_height)*original_width);
height=(int) max_height;
}else if(original_ratio>max_ratio){
height= (int)((max_width/original_width)*original_height);
width= (int)max_width;
}else{
height = max_height;
width = max_width;
}
//adjust the bitmap
Bitmap adjusted_bitmap = Bitmap.createScaledBitmap(bitmap_original,width,height,false);
//check rotation
Matrix matrix = new Matrix();
try{
ExifInterface exif = new ExifInterface(path);
int original_orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION , ExifInterface.ORIENTATION_UNDEFINED);
if(original_orientation == ExifInterface.ORIENTATION_ROTATE_90){
matrix.setRotate(90);
}else if(original_orientation == ExifInterface.ORIENTATION_180){
matrix.setRotate(180);
}else if(original_orientation == ExifInterface.ORIENTATION_270){
matrix.setRotate(270);
}
Bitmap rotated_adjusted_bitmap = Bitmap.createBitmap(adjusted_bitmap , 0 , 0 , adjusted_bitmap.getWidth(), adjusted_bitmap.getHeight(),matrix,true);
//lower the quality
ByteArrayOutputStream out = new ByteArrayOutputStream();
adjusted_rotated_bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
Bitmap adjusted_rotated_lowquality_bitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
}catch(IOException e){
}
}else{
//keep bitmap as is
Bitmap adjusted_bitmap = bitmap_original;
}
}
問題
上面的所有方法都可以正常工作,但是問題是在某些情況下,應用程序會因內存不足異常而崩潰。
我的代碼有問題嗎?
我對位圖和壓縮不了解很多。
謝謝你的幫助。
位圖通常需要時間,有時會阻塞I / O。 因此,在UI線程上調用imageWithText不是一個好習慣。
滑行被設計為具有靈活性,此問題很好地證明了該特性。
我強烈建議您使用下面的“滑行方式”。
ByteArrayOutputStream stream = new ByteArrayOutputStream();
yourBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
Glide.with(this).load(stream.toByteArray())
.asBitmap() .error(R.drawable.ic_thumb_placeholder)
.transform(new CircleTransform(this)).into(imageview);
有關更多詳細信息,請查看下面的鏈接
從圖庫中選擇圖像時,您可以獲取圖像uri:
Uri myUri = data.getData();
在將映像發送到服務器之前,您需要將該uri轉換為byteArray []
如下:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),myUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,0,baos);
byteArray[] bArray = baos.toByteArray();
If you want you can get the name of image as:
try (Cursor returnCursor = getContentResolver().query(myUri, null, null, null, null)) {
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
String FileName = returnCursor.getString(nameIndex);}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.