我有一个回收bitmap的问题.我有所有null和代码回收.不确定我做错了什么.
我的代码:
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp = DecodeImage.decodeFile(imgpath, 450, 450, true);
bmp.compress(Bitmap.CompressFormat.JPEG, 100 , stream);
Image img = Image.getInstance(stream.toByteArray());
错误信息:
07-12 15:44:11.924: E/AndroidRuntime(415): FATAL EXCEPTION: Thread-9850
07-12 15:44:11.924: E/AndroidRuntime(415): java.lang.IllegalStateException: Can't compress
a recycled bitmap
07-12 15:44:11.924: E/AndroidRuntime(415): at
android.graphics.Bitmap.checkRecycled(Bitmap.java:272)
07-12 15:44:11.924: E/AndroidRuntime(415): at
android.graphics.Bitmap.compress(Bitmap.java:896)
07-12 15:44:11.924: E/AndroidRuntime(415): at com.multiprvt.PDF$1.run(PDF.java:329)
07-12 15:44:11.924: E/AndroidRuntime(415): at java.lang.Thread.run(Thread.java:856)
解码为位图降低分辨率的类.
public class DecodeImage
{
//decodes image and scales it to reduce memory consumption
public static Bitmap decodeFile(File bitmapFile, int requiredWidth, int
requiredHeight, boolean quickAndDirty)
{
try
{
//Decode image size
BitmapFactory.Options bitmapSizeOptions = new BitmapFactory.Options();
bitmapSizeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null,
bitmapSizeOptions);
// load image using inSampleSize adapted to required image size
BitmapFactory.Options bitmapDecodeOptions = new BitmapFactory.Options();
bitmapDecodeOptions.inTempStorage = new byte[16 * 1024];
bitmapDecodeOptions.inSampleSize = computeInSampleSize(bitmapSizeOptions,
requiredWidth, requiredHeight, false);
bitmapDecodeOptions.inPurgeable = true;
bitmapDecodeOptions.inDither = !quickAndDirty;
bitmapDecodeOptions.inPreferredConfig = quickAndDirty ? Bitmap.Config.RGB_565 :
Bitmap.Config.ARGB_8888;
Bitmap decodedBitmap = BitmapFactory.decodeStream(new
FileInputStream(bitmapFile), null, bitmapDecodeOptions);
// scale bitmap to mathc required size (and keep aspect ratio)
float srcWidth = (float) bitmapDecodeOptions.outWidth;
float srcHeight = (float) bitmapDecodeOptions.outHeight;
float dstWidth = (float) requiredWidth;
float dstHeight = (float) requiredHeight;
float srcAspectRatio = srcWidth / srcHeight;
float dstAspectRatio = dstWidth / dstHeight;
// recycleDecodedBitmap is used to know if we must recycle intermediary
'decodedBitmap'
// (DO NOT recycle it right away: wait for end of bitmap manipulation process to avoid
// java.lang.RuntimeException: Canvas: trying to use a recycled bitmap
android.graphics.Bitmap@416ee7d8
// I do not excatly understand why, but this way it's OK
boolean recycleDecodedBitmap = false;
Bitmap scaledBitmap = decodedBitmap;
if (srcAspectRatio < dstAspectRatio)
{ scaledBitmap = getScaledBitmap(decodedBitmap, (int) dstWidth, (int)
(srcHeight * (dstWidth / srcWidth)));
// will recycle recycleDecodedBitmap
recycleDecodedBitmap = true;
}
else if (srcAspectRatio > dstAspectRatio)
{
scaledBitmap = getScaledBitmap(decodedBitmap, (int) (srcWidth * (dstHeight /
srcHeight)), (int) dstHeight);
recycleDecodedBitmap = true;
}
// crop image to match required image size
int scaledBitmapWidth = scaledBitmap.getWidth();
int scaledBitmapHeight = scaledBitmap.getHeight();
Bitmap croppedBitmap = scaledBitmap;
if (recycleDecodedBitmap)
{
decodedBitmap.recycle();
}
decodedBitmap = null;
scaledBitmap = null;
return croppedBitmap;
}
catch (Exception ex)
{
ex.printStackTrace();
}
return null;
}
/**
* compute powerOf2 or exact scale to be used as {@link
BitmapFactory.Options#inSampleSize} value (for subSampling)
*
* @param requiredWidth
* @param requiredHeight
* @param powerOf2
* weither we want a power of 2 sclae or not
* @return
*/
public static int computeInSampleSize(BitmapFactory.Options options, int dstWidth, int
dstHeight, boolean powerOf2)
{
int inSampleSize = 1;
// Raw height and width of image
final int srcHeight = options.outHeight;
final int srcWidth = options.outWidth;
if (powerOf2)
{
//Find the correct scale value. It should be the power of 2.
int tmpWidth = srcWidth, tmpHeight = srcHeight;
while (true)
{
if (tmpWidth / 2 < dstWidth || tmpHeight / 2 < dstHeight)
break;
tmpWidth /= 2;
tmpHeight /= 2;
inSampleSize *= 2;
}
}
else
{
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) srcHeight / (float) dstHeight);
final int widthRatio = Math.round((float) srcWidth / (float) dstWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
public static Bitmap drawableToBitmap(Drawable drawable)
{
if (drawable instanceof BitmapDrawable)
{
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
public static Bitmap getScaledBitmap(Bitmap bitmap, int newWidth, int newHeight)
{
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// RECREATE THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix,
false);
return resizedBitmap;
}
}
不知道它在哪里获得循环位图
解决方法:
您的源和缩放位图是相同的.在回收源之前检查是否相等.
Bitmap scaled = Bitmap.createScaledBitmap(src, ...):
if (src != scaled) {
src.recycle();
}
return scaled;
从Bitmap.createScaledBitmap(…)的文档:
尽可能创建从现有位图缩放的新位图.如果指定的宽度和高度与源位图的当前宽度和高度相同,则返回源位图,并且不会创建新的位图.
标签:android,bitmap 来源: https://codeday.me/bug/20190717/1490755.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。