參考博客:Android從相冊中獲取圖片以及路徑canvas
居然仍是有人在避免截取狀態欄,只是一種諷刺麼?好笑至極。app
1.1首先來看你一種截取屏幕dom
getWindow().getDecorView().setDrawingCacheEnabled(true); Bitmap screenBitmap = getWindow().getDecorView().getDrawingCache(); img_display.setImageBitmap(screenBitmap); getWindow().getDecorView().setDrawingCacheEnable(false);//這裏必須設置false,不然截圖只能調用一次
1.2下面的是每次均可以截取到(只能截取到可見屏幕部分,不可見部分沒法截取)ide
View decorView = getWindow().getDecorView(); Bitmap screenBitmap = Bitmap.createBitmap(decorView.getWidth(), decorView.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(screenBitmap); decorView.draw(canvas);
1.3截取可見與不可見屏幕部分(除ListView和GridView,只能截取ScrollView和HorizontalScrollView),緣由是ListView和GridView的適配機制是不斷的remove和add佈局
注意:這裏截取的是View而不是屏幕this
ScrollView和HorizontalScrollView必須只有一個子佈局,也就是說,他的子佈局的來做爲容器,它來做爲滾動控件url
ScrollView sv = (ScrollView)findViewById(R.id.scrollbox); LinearLayout panel= (LinearLayout)sv.findViewById(R.id.scrollbox_panel); int sumHeight = 0; for(int i=0;i<panel.getChildCount();i++) { sumHeight += panel.getChildAt(i).getHeight(); } Bitmap bmp = Bitmap.createBitmap(panel.getWidth(),sumHeight,Config.ARGB_8888); Canvas canvas = new Canvas(bmp); decorView.draw(canvas); //over 至於有人認爲,截取到的有些部分是黑色,那是英文你截取到的控件背景極可能是透明的,價格白色試試。
固然View內部提供了爲公開的View 截圖方法,createSnapshot,咱們使用時只須要反射就行spa
Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) { int width = mRight - mLeft; int height = mBottom - mTop; final AttachInfo attachInfo = mAttachInfo; final float scale = attachInfo != null ? attachInfo.mApplicationScale : 1.0f; width = (int) ((width * scale) + 0.5f); height = (int) ((height * scale) + 0.5f); Bitmap bitmap = Bitmap.createBitmap(width > 0 ? width : 1, height > 0 ? height : 1, quality); if (bitmap == null) { throw new OutOfMemoryError(); } Resources resources = getResources(); if (resources != null) { bitmap.setDensity(resources.getDisplayMetrics().densityDpi); } Canvas canvas; if (attachInfo != null) { canvas = attachInfo.mCanvas; if (canvas == null) { canvas = new Canvas(); } canvas.setBitmap(bitmap); // Temporarily clobber the cached Canvas in case one of our children // is also using a drawing cache. Without this, the children would // steal the canvas by attaching their own bitmap to it and bad, bad // things would happen (invisible views, corrupted drawings, etc.) attachInfo.mCanvas = null; } else { // This case should hopefully never or seldom happen canvas = new Canvas(bitmap); } if ((backgroundColor & 0xff000000) != 0) { bitmap.eraseColor(backgroundColor); } computeScroll(); final int restoreCount = canvas.save(); canvas.scale(scale, scale); canvas.translate(-mScrollX, -mScrollY); // Temporarily remove the dirty mask int flags = mPrivateFlags; mPrivateFlags &= ~DIRTY_MASK; // Fast path for layouts with no backgrounds if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { dispatchDraw(canvas); } else { draw(canvas); } mPrivateFlags = flags; canvas.restoreToCount(restoreCount); canvas.setBitmap(null); if (attachInfo != null) { // Restore the cached Canvas for our siblings attachInfo.mCanvas = canvas; } return bitmap; }
順便提一下,MediaStore保存圖片到相冊,在手機中,相冊和圖片的聯繫是,相冊中的圖片必定是圖片,但手機中的圖片不必定是相冊中的圖片。.net
也就是說,相冊並不保存圖片,而是保存圖片的路徑,在手機中,並非任何一張圖片都能保存在相冊中。rest
圖片保存是使用ContentProvider提供的接口,下面是相冊的Uri定位
Images.Media.EXTERNAL_CONTENT_URI
2.1最簡單的保存方式
String uriString = MediaStore.Images.Media.insertImage(context.getContentResolver(), bmp, "截圖-20141121", "這是個人截圖"); //返回值是 Uri 協議字符串
2.2最完整的保存方式
ContentResolver contentResolver = context.getContentResolver(); ContentValues values = new ContentValues(4); values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis()); values.put(Images.Media.MIME_TYPE, "image/png"); values.put(Images.Media.ORIENTATION, 0); values.put(Images.Media.TITLE, title); values.put(Images.Media.DESCRIPTION, description); Uri url = null; try { url = contentResolver.insert(Images.Media.EXTERNAL_CONTENT_URI, values); //其實質是返回 Image.Meida.DATA中圖片路徑path的轉變而成的uri if (bmp != null) { OutputStream imageOut = contentResolver.openOutputStream(url); try { bmp.compress(Bitmap.CompressFormat.PNG, 100, imageOut); } finally { imageOut.close(); } long id = ContentUris.parseId(url); Images.Thumbnails.getThumbnail(contentResolver, id,Images.Thumbnails.MINI_KIND, null);//獲取縮略圖 } else { Log.e("SAVE", "Failed to create thumbnail, removing original"); contentResolver.delete(url, null, null); url = null; } } catch (Exception e) { Log.e("SAVE", "Failed to insert image", e); if (url != null) { contentResolver.delete(url, null, null); url = null; } }
Images.Thumbnails.getThumbnail(contentResolver, id,Images.Thumbnails.MINI_KIND, null);//獲取縮略圖
2.3圖片的保存的另外一種方式(try catch太多,下面是簡寫方式,但代碼絕對正確)
File file = new File("/mnt/sdcard/Pictures/"+imageDate+".png"); FileOutputStream out = new FileOutputStream(file); out.flush(); out.close(); ContentResolver contentResolver = context.getContentResolver(); ContentValues values = new ContentValues(4); values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis()); values.put(Images.Media.MIME_TYPE, "image/png"); values.put(Images.Media.ORIENTATION, 0); values.put(Images.Media.TITLE, title); values.put(Images.Media.DESCRIPTION, description); values.put(Images.Media.DATA, file.getAbsolutePath()); //保存圖片路徑 Uri url = contentResolver.insert(Images.Media.EXTERNAL_CONTENT_URI, values);
try doing it;