Android 截圖並保存到相冊

參考博客:Android從相冊中獲取圖片以及路徑canvas

1、截圖方法

屏幕截圖,屏幕截圖只能截取到當前窗體的圖形,並不能截取,網上找了一大堆代碼,雷同度太多了,根本沒法截取到狀態欄,

居然仍是有人在避免截取狀態欄,只是一種諷刺麼?好笑至極。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;
    }

 

2、保存圖片到相冊

順便提一下,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;

相關文章
相關標籤/搜索