参考博客: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;