Android:位图压缩导致内存不足问题



我正在尝试压缩从图库中挑选或由相机捕获的位图,然后再发送到服务器。现在我按照以下步骤进行操作:

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 并不是好的做法。

Glide被设计为灵活的,这个问题表明 特质非常好。

下面的"滑行方式",我强烈推荐。

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);}

最新更新