国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android截屏方案實現(xiàn)原理解析

2019-10-22 18:20:01
字體:
來源:轉載
供稿:網(wǎng)友

Android截屏的原理:獲取具體需要截屏的區(qū)域的Bitmap,然后繪制在畫布上,保存為圖片后進行分享或者其它用途

在截屏功能中,有時需要截取全屏的內(nèi)容,有時需要截取超過一屏的內(nèi)容(比如:Listview,Scrollview,RecyclerView)。下面介紹各種場景獲取Bitmap的方法

普通截屏的實現(xiàn)

獲取當前Window的DrawingCache的方式,即decorView的DrawingCache

/**  * shot the current screen ,with the status but the status is trans *  *  * @param ctx current activity  */ public static Bitmap shotActivity(Activity ctx) {  View view = ctx.getWindow().getDecorView();  view.setDrawingCacheEnabled(true);  view.buildDrawingCache();  Bitmap bp = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, view.getMeasuredWidth(),    view.getMeasuredHeight());  view.setDrawingCacheEnabled(false);  view.destroyDrawingCache();  return bp; }

獲取當前View的DrawingCache

public static Bitmap getViewBp(View v) {    if (null == v) {      return null;    }    v.setDrawingCacheEnabled(true);    v.buildDrawingCache();    if (Build.VERSION.SDK_INT >= 11) {      v.measure(MeasureSpec.makeMeasureSpec(v.getWidth(),          MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(          v.getHeight(), MeasureSpec.EXACTLY));      v.layout((int) v.getX(), (int) v.getY(),          (int) v.getX() + v.getMeasuredWidth(),          (int) v.getY() + v.getMeasuredHeight());    } else {      v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));      v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());    }    Bitmap b = Bitmap.createBitmap(v.getDrawingCache(), 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());    v.setDrawingCacheEnabled(false);    v.destroyDrawingCache();    return b;  }

開源方案

在滾動視圖中,如果當前View并沒有在視圖中全部繪制出來,我們可以利用View的ScrollTo()和ScrollBy()方法來移動畫布,同時獲取當前View的可視部分的DrawingCache,最后進行拼接得到其Bitmap,參考: PGSSoft/scrollscreenshot@[Github] 。

Scrollview截屏

三個截屏中,ScrollView最簡單,因為ScrollView只有一個childView,雖然沒有全部顯示在界面上,但是已經(jīng)全部渲染繪制,因此可以直接 調(diào)用 scrollView.draw(canvas) 來完成截圖

public static Bitmap shotScrollView(ScrollView scrollView) {  int h = 0;  Bitmap bitmap = null;  for (int i = 0; i < scrollView.getChildCount(); i++) {   h += scrollView.getChildAt(i).getHeight();   scrollView.getChildAt(i).setBackgroundColor(Color.parseColor("#ffffff"));  }  bitmap = Bitmap.createBitmap(scrollView.getWidth(), h, Bitmap.Config.RGB_565);  final Canvas canvas = new Canvas(bitmap);  scrollView.draw(canvas);  return bitmap; }

Scrollview截屏

而ListView就是會回收與重用Item,并且只會繪制在屏幕上顯示的ItemView,根據(jù)stackoverflow上大神的建議,采用一個List來存儲Item的視圖,這種方案依然不夠好,當Item足夠多的時候,可能會發(fā)生oom。

public static Bitmap shotListView(ListView listview) {  ListAdapter adapter = listview.getAdapter();  int itemscount = adapter.getCount();  int allitemsheight = 0;  List<Bitmap> bmps = new ArrayList<Bitmap>();  for (int i = 0; i < itemscount; i++) {   View childView = adapter.getView(i, null, listview);   childView.measure(     View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),     View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));   childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());   childView.setDrawingCacheEnabled(true);   childView.buildDrawingCache();   bmps.add(childView.getDrawingCache());   allitemsheight += childView.getMeasuredHeight();  }  Bitmap bigbitmap =    Bitmap.createBitmap(listview.getMeasuredWidth(), allitemsheight, Bitmap.Config.ARGB_8888);  Canvas bigcanvas = new Canvas(bigbitmap);  Paint paint = new Paint();  int iHeight = 0;  for (int i = 0; i < bmps.size(); i++) {   Bitmap bmp = bmps.get(i);   bigcanvas.drawBitmap(bmp, 0, iHeight, paint);   iHeight += bmp.getHeight();   bmp.recycle();   bmp = null;  }  return bigbitmap; }

RecyclerView截屏

我們都知道,在新的Android版本中,已經(jīng)可以用RecyclerView來代替使用ListView的場景,相比較ListView,RecyclerView對Item View的緩存支持的更好。可以采用和ListView相同的方案,這里也是在stackoverflow上看到的方案。

public static Bitmap shotRecyclerView(RecyclerView view) {  RecyclerView.Adapter adapter = view.getAdapter();  Bitmap bigBitmap = null;  if (adapter != null) {   int size = adapter.getItemCount();   int height = 0;   Paint paint = new Paint();   int iHeight = 0;   final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);   // Use 1/8th of the available memory for this memory cache.   final int cacheSize = maxMemory / 8;   LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);   for (int i = 0; i < size; i++) {    RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i));    adapter.onBindViewHolder(holder, i);    holder.itemView.measure(      View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),      View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));    holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(),      holder.itemView.getMeasuredHeight());    holder.itemView.setDrawingCacheEnabled(true);    holder.itemView.buildDrawingCache();    Bitmap drawingCache = holder.itemView.getDrawingCache();    if (drawingCache != null) {     bitmaCache.put(String.valueOf(i), drawingCache);    }    height += holder.itemView.getMeasuredHeight();   }   bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);   Canvas bigCanvas = new Canvas(bigBitmap);   Drawable lBackground = view.getBackground();   if (lBackground instanceof ColorDrawable) {    ColorDrawable lColorDrawable = (ColorDrawable) lBackground;    int lColor = lColorDrawable.getColor();    bigCanvas.drawColor(lColor);   }   for (int i = 0; i < size; i++) {    Bitmap bitmap = bitmaCache.get(String.valueOf(i));    bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint);    iHeight += bitmap.getHeight();    bitmap.recycle();   }  }  return bigBitmap; }

上面的方法在截取存在異步加載圖片的RecyclerView時候會出現(xiàn)加載不出圖片的情況,這里再補充一種滾動式截屏的方法

public static void screenShotRecycleView(final RecyclerView mRecyclerView, final  RecycleViewRecCallback callBack) {    if (mRecyclerView == null) {      return;    }    BaseListFragment.MyAdapter adapter = (BaseListFragment.MyAdapter) mRecyclerView.getAdapter();    final Paint paint = new Paint();    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);    // Use 1/8th of the available memory for this memory cache.    final int cacheSize = maxMemory / 8;    LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);    final int oneScreenHeight = mRecyclerView.getMeasuredHeight();    int shotHeight = 0;    if (adapter != null && adapter.getData().size() > 0) {      int headerSize = adapter.getHeaderLayoutCount();      int dataSize = adapter.getData().size();      for (int i = 0; i < headerSize + dataSize; i++) {        BaseViewHolder holder = (BaseViewHolder) adapter.createViewHolder(mRecyclerView, adapter.getItemViewType(i));        if (i >= headerSize)          adapter.startConvert(holder, adapter.getData().get(i - headerSize));        holder.itemView.measure(            View.MeasureSpec.makeMeasureSpec(mRecyclerView.getWidth(), View.MeasureSpec.EXACTLY),            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));        holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(), holder.itemView.getMeasuredHeight());        holder.itemView.setDrawingCacheEnabled(true);        holder.itemView.buildDrawingCache();        Bitmap drawingCache = holder.itemView.getDrawingCache();        //holder.itemView.destroyDrawingCache();//釋放緩存占用的資源        if (drawingCache != null) {          bitmaCache.put(String.valueOf(i), drawingCache);        }        shotHeight += holder.itemView.getHeight();        if (shotHeight > 12000) {          //設置截圖最大值          if (callBack != null)            callBack.onRecFinished(null);          return;        }      }      //添加底部高度(加載更多或loading布局高度,此處為固定值:)      final int footHight = Util.dip2px(mRecyclerView.getContext(), 42);      shotHeight += footHight;      //返回到頂部      while (mRecyclerView.canScrollVertically(-1)) {        mRecyclerView.scrollBy(0, -oneScreenHeight);      }      //繪制截圖的背景      final Bitmap bigBitmap = Bitmap.createBitmap(mRecyclerView.getMeasuredWidth(), shotHeight, Bitmap.Config.ARGB_8888);      final Canvas bigCanvas = new Canvas(bigBitmap);      Drawable lBackground = mRecyclerView.getBackground();      if (lBackground instanceof ColorDrawable) {        ColorDrawable lColorDrawable = (ColorDrawable) lBackground;        int lColor = lColorDrawable.getColor();        bigCanvas.drawColor(lColor);      }      final int[] drawOffset = {0};      final Canvas canvas = new Canvas();      if (shotHeight <= oneScreenHeight) {        //僅有一頁        Bitmap bitmap = Bitmap.createBitmap(mRecyclerView.getWidth(), mRecyclerView.getHeight(), Bitmap.Config.ARGB_8888);        canvas.setBitmap(bitmap);        mRecyclerView.draw(canvas);        if (callBack != null)          callBack.onRecFinished(bitmap);      } else {        //超過一頁        final int finalShotHeight = shotHeight;        mRecyclerView.postDelayed(new Runnable() {          @Override          public void run() {            if ((drawOffset[0] + oneScreenHeight < finalShotHeight)) {              //超過一屏              Bitmap bitmap = Bitmap.createBitmap(mRecyclerView.getWidth(), mRecyclerView.getHeight(), Bitmap.Config.ARGB_8888);              canvas.setBitmap(bitmap);              mRecyclerView.draw(canvas);              bigCanvas.drawBitmap(bitmap, 0, drawOffset[0], paint);              drawOffset[0] += oneScreenHeight;              mRecyclerView.scrollBy(0, oneScreenHeight);              try {                bitmap.recycle();              } catch (Exception ex) {                ex.printStackTrace();              }              mRecyclerView.postDelayed(this, 10);            } else {              //不足一屏時的處理              int leftHeight = finalShotHeight - drawOffset[0] - footHight;              mRecyclerView.scrollBy(0, leftHeight);              int top = oneScreenHeight - (finalShotHeight - drawOffset[0]);              if (top > 0 && leftHeight > 0) {                Bitmap bitmap = Bitmap.createBitmap(mRecyclerView.getWidth(), mRecyclerView.getHeight(), Bitmap.Config.ARGB_8888);                canvas.setBitmap(bitmap);                mRecyclerView.draw(canvas);                //截圖,只要補足的那塊圖                bitmap = Bitmap.createBitmap(bitmap, 0, top, bitmap.getWidth(), leftHeight, null, false);                bigCanvas.drawBitmap(bitmap, 0, drawOffset[0], paint);                try {                  bitmap.recycle();                } catch (Exception ex) {                  ex.printStackTrace();                }              }              if (callBack != null)                callBack.onRecFinished(bigBitmap);            }          }        }, 10);      }    }  }  public interface RecycleViewRecCallback {    void onRecFinished(Bitmap bitmap);  }

相信有不少小伙伴用BRVH第三方庫來做recycleview的適配器的。使用這個庫的話再用上面的方法會報角標越界的錯誤,看了BRVH的源碼

public void onBindViewHolder(ViewHolder holder, int positions) {    int viewType = holder.getItemViewType();    switch(viewType) {    case 0:      this.convert((BaseViewHolder)holder, this.mData.get(holder.getLayoutPosition() - this.getHeaderLayoutCount()));    case 273:    case 819:    case 1365:      break;    case 546:      this.addLoadMore(holder);      break;    default:      this.convert((BaseViewHolder)holder, this.mData.get(holder.getLayoutPosition() - this.getHeaderLayoutCount()));      this.onBindDefViewHolder((BaseViewHolder)holder, this.mData.get(holder.getLayoutPosition() - this.getHeaderLayoutCount()));    }  }

在調(diào)用 adapter.onBindViewHolder 時,因為里面的 position 參數(shù)未使用,里面用的計算 holder.getLayoutPosition() - this.getHeaderLayoutCount() 的值一直是-1導致角標越界報錯。

本人理解,RecyclerView的截屏原理是,首先構造每個item的ViewHolder,然后調(diào)用具體設置數(shù)據(jù)到每個item的方法,此時cache中就存有item的內(nèi)容,此時繪制就能獲取到完整的內(nèi)容。采用v7包中的 onBindViewHolder 方法即可,或者是BRVH的 convert 方法,可以看到BRVH中沒有暴露出這個方法,而且唯一暴露出的 onBindViewHolder 還會報角標越界錯誤,此時我們就需要在BRVH的基礎上暴露出 convert 即可,代碼如下

public class MyAdapter extends BaseQuickAdapter<T> {    public MyAdapter() {      super(getItemLayoutResId(), datas);    }    /**     * 用于對外暴露convert方法,構造緩存視圖(截屏用)     * @param viewHolder     * @param t     */    public void startConvert(BaseViewHolder viewHolder, T t){      convert(viewHolder,t);    }    @Override    protected void convert(BaseViewHolder viewHolder, T t) {      bindView(viewHolder, t);    }  }

然后將上面所述的獲取Bitmap方法修改一下

/**   * 截取recycler view   */  public static Bitmap getRecyclerViewScreenshot(RecyclerView view) {    BaseListFragment.MyAdapter adapter = (BaseListFragment.MyAdapter) view.getAdapter();    Bitmap bigBitmap = null;    if (adapter != null) {      int size = adapter.getData().size();      int height = 0;      Paint paint = new Paint();      int iHeight = 0;      final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);      // Use 1/8th of the available memory for this memory cache.      final int cacheSize = maxMemory / 8;      LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);      for (int i = 0; i < size; i++) {        BaseViewHolder holder = (BaseViewHolder) adapter.createViewHolder(view, adapter.getItemViewType(i));        //此處需要調(diào)用convert方法,否則繪制出來的都是空的item        adapter.startConvert(holder, adapter.getData().get(i));        holder.itemView.measure(            View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));        holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(),            holder.itemView.getMeasuredHeight());        holder.itemView.setDrawingCacheEnabled(true);        holder.itemView.buildDrawingCache();        Bitmap drawingCache = holder.itemView.getDrawingCache();        if (drawingCache != null) {          bitmaCache.put(String.valueOf(i), drawingCache);        }        height += holder.itemView.getMeasuredHeight();      }      bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);      Canvas bigCanvas = new Canvas(bigBitmap);      Drawable lBackground = view.getBackground();      if (lBackground instanceof ColorDrawable) {        ColorDrawable lColorDrawable = (ColorDrawable) lBackground;        int lColor = lColorDrawable.getColor();        bigCanvas.drawColor(lColor);      }      for (int i = 0; i < size; i++) {        Bitmap bitmap = bitmaCache.get(String.valueOf(i));        bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint);        iHeight += bitmap.getHeight();        bitmap.recycle();      }    }    return bigBitmap;  }

合成Bitmap

比如四張合成一張

/**   * 將四張圖拼成一張   *   * @param pic1 圖一   * @param pic2 圖二   * @param pic3 圖三   * @param pic4 圖四   * @return only_bitmap   * 詳情見說明:{@link com.bertadata.qxb.util.ScreenShotUtils}   */  public static Bitmap combineBitmapsIntoOnlyOne(Bitmap pic1, Bitmap pic2, Bitmap pic3, Bitmap pic4, Activity context) {    int w_total = pic2.getWidth();    int h_total = pic1.getHeight() + pic2.getHeight() + pic3.getHeight() + pic4.getHeight();    int h_pic1 = pic1.getHeight();    int h_pic4 = pic4.getHeight();    int h_pic12 = pic1.getHeight() + pic2.getHeight();    //此處為防止OOM需要對高度做限制    if (h_total > HEIGHTLIMIT) {      return null;    }    Bitmap only_bitmap = Bitmap.createBitmap(w_total, h_total, Bitmap.Config.ARGB_4444);    Canvas canvas = new Canvas(only_bitmap);    canvas.drawColor(ContextCompat.getColor(context, R.color.color_content_bg));    canvas.drawBitmap(pic1, 0, 0, null);    canvas.drawBitmap(pic2, 0, h_pic1, null);    canvas.drawBitmap(pic3, 0, h_pic12, null);    canvas.drawBitmap(pic4, 0, h_total - h_pic4, null);    return only_bitmap;  }

圖片后期處理

/**   * 將傳入的Bitmap合理壓縮后輸出到系統(tǒng)截屏目錄下   * 命名格式為:Screenshot+時間戳+啟信寶報名.jpg   * 同時通知系統(tǒng)重新掃描系統(tǒng)文件   *   * @param pic1  圖一 標題欄截圖   * @param pic2  圖二 scrollview截圖   * @param context 用于通知重新掃描文件系統(tǒng),為提升性能可去掉   *        詳情見說明:{@link com.bertadata.qxb.util.ScreenShotUtils}   */  public static void savingBitmapIntoFile(final Bitmap pic1, final Bitmap pic2, final Activity context, final BitmapAndFileCallBack callBack) {    if (context == null || context.isFinishing()) {      return;    }    Thread thread = new Thread(new Runnable() {      @Override      public void run() {        String fileReturnPath = "";        int w = pic1.getWidth();        Bitmap bottom = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_picture_combine_bottom);        Bitmap top_banner = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_picture_combine_top);        Bitmap bitmap_bottom = anyRatioCompressing(bottom, (float) w / bottom.getWidth(), (float) w / bottom.getWidth());        Bitmap bitmap_top = anyRatioCompressing(top_banner, (float) w / bottom.getWidth(), (float) w / bottom.getWidth());        final Bitmap only_bitmap = combineBitmapsIntoOnlyOne(bitmap_top, pic1, pic2, bitmap_bottom, context);        // 獲取當前時間        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-ms", Locale.getDefault());        String data = sdf.format(new Date());        // 獲取內(nèi)存路徑        // 設置圖片路徑+命名規(guī)范        // 聲明輸出文件        String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath();        String fileTitle = "Screenshot_" + data + "_com.bertadata.qxb.biz_info.jpg";        String filePath = storagePath + "/DCIM/";        final String fileAbsolutePath = filePath + fileTitle;        File file = new File(fileAbsolutePath);        /**         * 質(zhì)壓與比壓結合         * 分級壓縮         * 輸出文件         */        if (only_bitmap != null) {          try {            // 首先,對原圖進行一步質(zhì)量壓縮,形成初步文件            FileOutputStream fos = new FileOutputStream(file);            only_bitmap.compress(Bitmap.CompressFormat.JPEG, 50, fos);            // 另建一個文件other_file預備輸出            String other_fileTitle = "Screenshot_" + data + "_com.bertadata.qxb.jpg";            String other_fileAbsolutePath = filePath + other_fileTitle;            File other_file = new File(other_fileAbsolutePath);            FileOutputStream other_fos = new FileOutputStream(other_file);            // 其次,要判斷質(zhì)壓之后的文件大小,按文件大小分級進行處理            long file_size = file.length() / 1024; // size of file(KB)            if (file_size < 0 || !(file.exists())) {              // 零級: 文件判空              throw new NullPointerException();            } else if (file_size > 0 && file_size <= 256) {              // 一級: 直接輸出              deleteFile(other_file);              // 通知刷新文件系統(tǒng),顯示最新截取的圖文件              fileReturnPath = fileAbsolutePath;              context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + fileAbsolutePath)));            } else if (file_size > 256 && file_size <= 768) {              // 二級: 簡單壓縮:壓縮為原比例的3/4,質(zhì)壓為50%              anyRatioCompressing(only_bitmap, (float) 3 / 4, (float) 3 / 4).compress(Bitmap.CompressFormat.JPEG, 40, other_fos);              deleteFile(file);              // 通知刷新文件系統(tǒng),顯示最新截取的圖文件              fileReturnPath = other_fileAbsolutePath;              context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + other_fileAbsolutePath)));            } else if (file_size > 768 && file_size <= 1280) {              // 三級: 中度壓縮:壓縮為原比例的1/2,質(zhì)壓為40%              anyRatioCompressing(only_bitmap, (float) 1 / 2, (float) 1 / 2).compress(Bitmap.CompressFormat.JPEG, 40, other_fos);              deleteFile(file);              // 通知刷新文件系統(tǒng),顯示最新截取的圖文件              fileReturnPath = other_fileAbsolutePath;              context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + other_fileAbsolutePath)));            } else if (file_size > 1280 && file_size <= 2048) {              // 四級: 大幅壓縮:壓縮為原比例的1/3,質(zhì)壓為40%              anyRatioCompressing(only_bitmap, (float) 1 / 3, (float) 1 / 3).compress(Bitmap.CompressFormat.JPEG, 40, other_fos);              deleteFile(file);              // 通知刷新文件系統(tǒng),顯示最新截取的圖文件              fileReturnPath = other_fileAbsolutePath;              context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + other_fileAbsolutePath)));            } else if (file_size > 2048) {              // 五級: 中度壓縮:壓縮為原比例的1/2,質(zhì)壓為40%              anyRatioCompressing(only_bitmap, (float) 1 / 2, (float) 1 / 2).compress(Bitmap.CompressFormat.JPEG, 40, other_fos);              deleteFile(file);              // 通知刷新文件系統(tǒng),顯示最新截取的圖文件              fileReturnPath = other_fileAbsolutePath;              context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + other_fileAbsolutePath)));            }            // 注銷fos;            fos.flush();            other_fos.flush();            other_fos.close();            fos.close();            //callback用于回傳保存成功的路徑以及Bitmap            callBack.onSuccess(only_bitmap, fileReturnPath);          } catch (Exception e) {            e.printStackTrace();          }        } else callBack.onSuccess(null, "");      }    });    thread.start();  }/**   * 可實現(xiàn)任意寬高比例壓縮(寬高壓比可不同)的壓縮方法(主要用于微壓)   *   * @param bitmap    源圖   * @param width_ratio 寬壓比(float)(0<&&<1)   * @param height_ratio 高壓比(float)(0<&&<1)   * @return 目標圖片   * <p>   */  public static Bitmap anyRatioCompressing(Bitmap bitmap, float width_ratio, float height_ratio) {    Matrix matrix = new Matrix();    matrix.postScale(width_ratio, height_ratio);    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);  }

總結

以上所述是小編給大家介紹的Android截屏方案實現(xiàn)原理解析,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VEVB武林網(wǎng)網(wǎng)站的支持!


注:相關教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 教育| 武威市| 石棉县| 迭部县| 通辽市| 邛崃市| 绵阳市| 新野县| 齐齐哈尔市| 新昌县| 涞水县| 剑阁县| 神农架林区| 永年县| 永安市| 太白县| 邵阳县| 竹北市| 榆中县| 茌平县| 林州市| 银川市| 巨鹿县| 靖边县| 彰化市| 黎平县| 鄄城县| 新沂市| 介休市| 右玉县| 南开区| 中宁县| 玉环县| 宕昌县| 清流县| 鹰潭市| 土默特右旗| 开平市| 綦江县| 沈丘县| 东安县|