(1)BitmapFactory类相关
(1)常用的四个decode函数的使用
public static Bitmap decodeResource(Resources res, int id, Options opts):图片保存在res/drawable-xxx文件夹时,使用该函数
public static Bitmap decodeFile(String pathName, Options opts):图片源已知是绝对路径时使用该函数
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts):图片源已知是数据库源uri时可使用该函数
ParcelFileDescriptor pfd = context.getContentResolver() .openFileDescriptor(sourceUri, "r"); FileDescriptor fd = null; Bitmap bitmap = null; if (pfd != null) { fd = pfd.getFileDescriptor(); } try { if (fd != null) { bitmap = BitmapFactory.decodeFileDescriptor(fd, null, options); } } catch (OutOfMemoryError e) {
public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts):图片源已知是数据库源uri时可使用该函数
InputStream is = null; try { is = mContext.getContentResolver().openInputStream(uri); BitmapFactory.decodeStream(is, null, o);
说明:
1.第一个函数可以在UI线程中直接使用,后三个函数必须使用异步线程。后两个函数有何区别,暂时不明,测试二者所花时间差不多。
2.outPadding一般置为null,如果图片源的bitmap有边界,可以通过该参数获取一个Rect边界对象。
(2)避免OutOfMemoryError
如果允许在一定条件下对原图进行采样可以很好的规避此问题,同时可以得到不为空的bitmap进行下一步处理。
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(sourceUri, "r"); FileDescriptor fd = null; Bitmap bitmap = null; if (pfd != null) { fd = pfd.getFileDescriptor(); } try { if (fd != null) { bitmap = BitmapFactory.decodeFileDescriptor(fd, null, options); } } catch (OutOfMemoryError e) { // / M: As there is a chance no enough dvm memory for decoded // Bitmap, // Skia will return a null Bitmap. In this case, we have to // downscale the decoded Bitmap by increase the options.inSampleSize final int maxTryNum = 8; for (int i = 0; i < maxTryNum; i++) { // we increase inSampleSize to expect a smaller Bitamp options.inSampleSize *= 2; try { bitmap = BitmapFactory.decodeFileDescriptor(fd, null, options); } catch (OutOfMemoryError e1) { Log.w(LOGTAG, " saveBitmap :out of memory when decoding:" + e1); bitmap = null; } if (bitmap != null) break; } } finally { if (pfd != null) { Utils.closeSilently(pfd); } }
(3)不耗时获取图片源的宽和高数据。使用如下方式decode不会把数据读取到内存,从而不耗时。
InputStream isStream = mContext.getContentResolver().openInputStream(uri); BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inJustDecodeBounds = true; BitmapFactory.decodeStream(isStream, null, opt); photoWidth = opt.outWidth; photoHeight = opt.outHeight;
(4)BitmapFactory.Options常用相关属性
public Bitmap.Config inPreferredConfig:默认值为Bitmap.Config.ARGB_8888;
public int inSampleSize:采样率,必须是2的指数值。
public boolean inJustDecodeBounds