在android開發中, 在一些編輯我的信息的時候,常常會有頭像這麼一個東西,就兩個方面,調用系統相機拍照,調用系統圖庫獲取圖片.可是每每會遇到各類問題:java
1.oom android
2.圖片方向不對canvas
3.activity result 的時候data == null瀏覽器
4.調用圖庫的時候沒找到軟件app
嘿嘿..開代碼:ide
首先是調用系統拍照,和圖庫的代碼.net
package com.chzh.fitter.util; import java.io.File; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.provider.MediaStore; import android.widget.Toast; //在onActivityResult方法中根據requestCode和resultCode來獲取當前拍照的圖片地址。 //注意:這裏有個問題,在有些機型當中(如SamsungI93九、note2等)碰見了當拍照並存儲以後,intent當中獲得的data爲空: /** * data = null 的狀況主要是因爲拍照的時候橫屏了,致使從新create, 普通的解決方法能夠在sharedpreference裏面保存拍照文件的路徑(onSaveInstance保存), * 在onRestoreSaveInstance裏面在獲取出來. * 最簡單的能夠用fileUtil 裏面的一個靜態變量保存起來.. * */ public class CameraUtil { private static final String IMAGE_TYPE = "image/*"; private Context mContext; public CameraUtil(Context context) { mContext = context; } /** * 打開照相機 * @param activity 當前的activity * @param requestCode 拍照成功時activity forResult 的時候的requestCode * @param photoFile 拍照完畢時,圖片保存的位置 */ public void openCamera(Activity activity, int requestCode, File photoFile) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); activity.startActivityForResult(intent, requestCode); } /** * 本地照片調用 * @param activity * @param requestCode */ public void openPhotos(Activity activity, int requestCode) { if (openPhotosNormal(activity, requestCode) && openPhotosBrowser(activity, requestCode) && openPhotosFinally()); } /** * PopupMenu打開本地相冊. */ private boolean openPhotosNormal(Activity activity, int actResultCode) { Intent intent = new Intent(Intent.ACTION_PICK, null); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_TYPE); try { activity.startActivityForResult(intent, actResultCode); } catch (android.content.ActivityNotFoundException e) { return true; } return false; } /** * 打開其餘的一文件瀏覽器,若是沒有本地相冊的話 */ private boolean openPhotosBrowser(Activity activity, int requestCode) { Toast.makeText(mContext, "沒有相冊軟件,運行文件瀏覽器", Toast.LENGTH_LONG).show(); Intent intent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT" intent.setType(IMAGE_TYPE); // 查看類型 String IMAGE_UNSPECIFIED = // "image/*"; Intent wrapperIntent = Intent.createChooser(intent, null); try { activity.startActivityForResult(wrapperIntent, requestCode); } catch (android.content.ActivityNotFoundException e1) { return true; } return false; } /** * 這個是找不到相關的圖片瀏覽器,或者相冊 */ private boolean openPhotosFinally() { Toast.makeText(mContext, "您的系統沒有文件瀏覽器或則相冊支持,請安裝!", Toast.LENGTH_LONG).show(); return false; } /** * 獲取從本地圖庫返回來的時候的URI解析出來的文件路徑 * @return */ public static String getPhotoPathByLocalUri(Context context, Intent data) { Uri selectedImage = data.getData(); String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = context.getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); return picturePath; } }
接下來是解決oom的debug
package com.chzh.fitter.util; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.IOException; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.media.ExifInterface; import android.net.Uri; import android.util.Log; import android.widget.ImageView; import com.androidquery.util.AQUtility; /** * @author jarrahwu * */ public class ImageUtil { /** * Utility method for downsampling images. * * @param path * the file path * @param data * if file path is null, provide the image data directly * @param target * the target dimension * @param isWidth * use width as target, otherwise use the higher value of height * or width * @param round * corner radius * @return the resized image */ public static Bitmap getResizedImage(String path, byte[] data, int target, boolean isWidth, int round) { Options options = null; if (target > 0) { Options info = new Options(); info.inJustDecodeBounds = true; //設置這兩個屬性能夠減小內存損耗 info.inInputShareable = true; info.inPurgeable = true; decode(path, data, info); int dim = info.outWidth; if (!isWidth) dim = Math.max(dim, info.outHeight); int ssize = sampleSize(dim, target); options = new Options(); options.inSampleSize = ssize; } Bitmap bm = null; try { bm = decode(path, data, options); } catch (OutOfMemoryError e) { L.red(e.toString()); e.printStackTrace(); } if (round > 0) { bm = getRoundedCornerBitmap(bm, round); } return bm; } private static Bitmap decode(String path, byte[] data, BitmapFactory.Options options) { Bitmap result = null; if (path != null) { result = decodeFile(path, options); } else if (data != null) { // AQUtility.debug("decoding byte[]"); result = BitmapFactory.decodeByteArray(data, 0, data.length, options); } if (result == null && options != null && !options.inJustDecodeBounds) { AQUtility.debug("decode image failed", path); } return result; } private static Bitmap decodeFile(String path, BitmapFactory.Options options) { Bitmap result = null; if (options == null) { options = new Options(); } options.inInputShareable = true; options.inPurgeable = true; FileInputStream fis = null; try { fis = new FileInputStream(path); FileDescriptor fd = fis.getFD(); // AQUtility.debug("decoding file"); // AQUtility.time("decode file"); result = BitmapFactory.decodeFileDescriptor(fd, null, options); // AQUtility.timeEnd("decode file", 0); } catch (IOException e) { Log.error("TAG",e.toString()) } finally { fis.close() } return result; } private static int sampleSize(int width, int target) { int result = 1; for (int i = 0; i < 10; i++) { if (width < target * 2) { break; } width = width / 2; result = result * 2; } return result; } /** * 獲取圓角的bitmap * @param bitmap * @param pixels * @return */ private static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); final float roundPx = pixels; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } /** * auto fix the imageOrientation * @param bm source * @param iv imageView if set invloke it's setImageBitmap() otherwise do nothing * @param uri image Uri if null user path * @param path image path if null use uri */ public static Bitmap autoFixOrientation(Bitmap bm, ImageView iv, Uri uri,String path) { int deg = 0; try { ExifInterface exif = null; if (uri == null) { exif = new ExifInterface(path); } else if (path == null) { exif = new ExifInterface(uri.getPath()); } if (exif == null) { Log.error("TAG","exif is null check your uri or path"); return bm; } String rotate = exif.getAttribute(ExifInterface.TAG_ORIENTATION); int rotateValue = Integer.parseInt(rotate); System.out.println("orientetion : " + rotateValue); switch (rotateValue) { case ExifInterface.ORIENTATION_ROTATE_90: deg = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: deg = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: deg = 270; break; default: deg = 0; break; } } catch (Exception ee) { Log.d("catch img error", "return"); if(iv != null) iv.setImageBitmap(bm); return bm; } Matrix m = new Matrix(); m.preRotate(deg); bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true); //bm = Compress(bm, 75); if(iv != null) iv.setImageBitmap(bm); return bm; } }
若是想要代碼Demo的話,能夠留言.有什麼坑爹的地方,多多拍磚..over.code