手记

截屏,拼接图片,分享

现在有一个需求是要求截屏,下载自己二维码,拼接图片,在分享,截屏俩种方式,代码如下。如有疑问(993987402)

private JointBitmap view;
  private ImageView mView;
  // 加载成功
  private static final int LOAD_SUCCESS = 1;
  // 加载失败
  private static final int LOAD_ERROR = -1;
  // 用于异步的显示图片
  private Handler mHandler=new Handler(){
      @Override
      public void handleMessage(Message msg) {
          super.handleMessage(msg);
          switch (msg.what) {
              //下载成功
              case 1:
                  // 获取图片的文件对象
                  File file = new File(Environment.getExternalStorageDirectory(), "pic.jpg");
                  FileInputStream fis = null;
                  try {
                      fis = new FileInputStream(file);
                      Bitmap bitmap = BitmapFactory.decodeStream(fis);
                      // image.setImageBitmap(bitmap);
                      setNewBimap(bitmap);

                  } catch (FileNotFoundException e) {
                      e.printStackTrace();
                  }

                  break;
              //下载失败
              case 0:
                  Log.d("TAG","失败了");
                  Toast.makeText(MainActivity.this, "加载失败", Toast.LENGTH_SHORT).show();

                  break;
          }
      }
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      permissionHelper = PermissionHelper.getInstance(this);
      mView= (ImageView) findViewById(R.id.image_view);
      findViewById(R.id.main_btn).setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              setPermission();
          }
      });
  }

  /**
   * 请求权限
   */
  private void setPermission(){
      if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
          //请求权限
          setPommisions();
          view();
      }else{
          //不需要
          permissionsAllowed();
      }
  }

  /**
   * 请求权限
   */
  private void setPommisions(){
      //setForceAccepting 是否强制让用户接受权限
      permissionHelper.setForceAccepting(false).request(PERMISSIONS_STORAGE);

  }
  /**
   * 权限申请
   */
  private PermissionHelper permissionHelper;
  public  String[] PERMISSIONS_STORAGE = {
          Manifest.permission.READ_EXTERNAL_STORAGE,
          Manifest.permission.WRITE_EXTERNAL_STORAGE,
          Manifest.permission.READ_PHONE_STATE
  };

  /**
   * 不用申请权限(6.0权限以下)
   */
  private  void permissionsAllowed(){
      view();
  }


  /**
   * 获取权限返回是否通过
   * @param requestCode
   * @param resultCode
   * @param data
   */
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      permissionHelper.onActivityForResult(requestCode);
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      permissionHelper.onRequestPermissionsResult(requestCode,permissions,grantResults);
  }

  /**
   * 下面是所有的定义的接口类的方法。
   * @param permissionName
   * 第一个是代表不用申请权限许可的
   */
  @Override
  public void onPermissionGranted(@NonNull String[] permissionName) {
      permissionsAllowed();
  }
  @Override
  public void onPermissionPreGranted(@NonNull String permissionsName) {
      permissionsAllowed();
  }

  /**
   * 关于权限被拒绝(拒绝的时候再次 申请)
   * @param permissionName
   */
  @Override
  public void onPermissionDeclined(@NonNull String[] permissionName) {

  }

  /**
   * 许可需要说明
   * @param permissionName
   */
  @Override
  public void onPermissionNeedExplanation(@NonNull String permissionName) {

  }

  /**
   * 在权限上被拒绝
   * @param permissionName
   */
  @Override
  public void onPermissionReallyDeclined(@NonNull String permissionName) {

  }

  /**
   * 不限制权限
   */
  @Override
  public void onNoPermissionNeeded() {

  }

  /**
   * 截屏显示
   */
  private Bitmap screenshot() {
      // 获取屏幕
      View dView = getWindow().getDecorView();
      dView.setDrawingCacheEnabled(true);
      dView.buildDrawingCache();
      Bitmap bmp = dView.getDrawingCache();
      if (bmp != null) {
          try {
              // 获取内置SD卡路径
              String sdCardPath = Environment.getExternalStorageDirectory().getPath();
              // 图片文件路径
              String filePath = sdCardPath + File.separator + "screenshot.png";

              File file = new File(filePath);
              FileOutputStream os = new FileOutputStream(file);
              bmp.compress(Bitmap.CompressFormat.PNG, 100, os);
              os.flush();
              os.close();
          } catch (Exception e) {
          }
      }
      return bmp;
  }


  /**
   * 组合图片拼接
   * @param bit2
   */
  private void setNewBimap(Bitmap bit2){

      Bitmap bm =screenshot();
      // 将图片显示到ImageView中
      view = new JointBitmap(this, bm, bit2);
      Bitmap bitmap = view.newBitmap(bm, bit2);//imageView_joint
      if (bitmap != null) {
          try {
              // 获取内置SD卡路径
              String sdCardPath = Environment.getExternalStorageDirectory().getPath();
              // 图片文件路径
              String filePath = sdCardPath + File.separator + "sharepicure.png";

              File file = new File(filePath);
              FileOutputStream os = new FileOutputStream(file);
              bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
              os.flush();
              os.close();
          } catch (Exception e) {
          }
      }
      mView.setImageBitmap(bitmap);
  }

  /**
   * 点击下载图片
   */
  public void view(){
// 开启新的线程用于下载图片
      new Thread(new Runnable() {
          public void run() {

              getPicture();
          }
      }).start();
  }
  //下载图片的主方法
  private void getPicture() {

      URL url = null;
      InputStream is = null;
      FileOutputStream fos = null;
      try {
          //构建图片的url地址
          url = new URL("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504262170401&di=e8bcb963760c37dc7fd5ddee48cb40cd&imgtype=0&src=http%3A%2F%2Fwww.zhlzw.com%2FUploadFiles%2FArticle_UploadFiles%2F201204%2F20120412123921838.jpg");
          //开启连接
          HttpURLConnection conn = (HttpURLConnection) url.openConnection();
          //设置超时的时间,5000毫秒即5秒
          conn.setConnectTimeout(5000);
          //设置获取图片的方式为GET
          conn.setRequestMethod("GET");
          //响应码为200,则访问成功
          if (conn.getResponseCode() == 200) {
              //获取连接的输入流,这个输入流就是图片的输入流
              is = conn.getInputStream();
              //构建一个file对象用于存储图片
              File file = new File(Environment.getExternalStorageDirectory(), "pic.jpg");
              fos = new FileOutputStream(file);
              int len = 0;
              byte[] buffer = new byte[1024];
              //将输入流写入到我们定义好的文件中
              while ((len = is.read(buffer)) != -1) {
                  fos.write(buffer, 0, len);
              }
              //将缓冲刷入文件
              fos.flush();
              //告诉handler,图片已经下载成功
              mHandler.sendEmptyMessage(1);
          }
      } catch (Exception e) {
          //告诉handler,图片已经下载失败
          mHandler.sendEmptyMessage(0);
          e.printStackTrace();
      } finally {
          //在最后,将各种流关闭
          try {
              if (is != null) {
                  is.close();
              }
              if (fos != null) {
                  fos.close();
              }
          } catch (Exception e) {
              mHandler.sendEmptyMessage(0);
              e.printStackTrace();
          }
      }
  }
这个事拼接图片;
private Bitmap bitmap;

public JointBitmap(Context context, Bitmap bit1, Bitmap bit2) {
    super(context);
    // bitmap = newBitmap(bit1,bit2);
}

/**
 * 拼接图片
 *
 * @param bit1
 * @param bit2
 * @return 返回拼接后的Bitmap
 */
public Bitmap newBitmap(Bitmap bit1, Bitmap bit2) {

    int width = bit1.getWidth();
    int height = bit1.getHeight() + bit2.getHeight();
    //创建一个空的Bitmap(内存区域),宽度等于第一张图片的宽度,高度等于两张图片高度总和
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    //将bitmap放置到绘制区域,并将要拼接的图片绘制到指定内存区域
    Canvas canvas = new Canvas(bitmap);
    canvas.drawBitmap(bit1, 0, 0, null);
    canvas.drawBitmap(bit2, 0, bit1.getHeight(), null);
    return bitmap;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawBitmap(bitmap, 0, 0, null);
    bitmap.recycle();
}

public JointBitmap(Context context) {
    super(context);
}

public JointBitmap(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public JointBitmap(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}
5.0以上截屏大家都这么做。
  private static final String TAG ="otouzi";
    private static final int REQUEST_CODE = 100;
    private static String STORE_DIRECTORY;
    private static int IMAGES_PRODUCED;
    private static final String SCREENCAP_NAME = "screencap";
    private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
    private static MediaProjection sMediaProjection;

    private MediaProjectionManager mProjectionManager;
    private ImageReader mImageReader;
    private Handler mHandler;
    private Display mDisplay;//显示
    private VirtualDisplay mVirtualDisplay;
    private int mDensity;
    private int mWidth;
    private int mHeight;
    private int mRotation;
    private OrientationChangeCallback mOrientationChangeCallback;
    private String path;
    private ImageView imageView;
    private ImageView text_imageView2;
    private Bitmap mBitmap;//ImageLoate本地的图片
    private Handler mHandlerWolder=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (msg.what==1){
                setImageview();
            }
        }
    };



    /****************************************** Activity Lifecycle methods ************************/
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_testview);
        /**
         * 系统向用户请求屏幕录制的相关权限,首先获取MediaProjectionManager,
         * 和其他的Manager一样通过 Context.getSystemService() 传入参数MEDIA_PROJECTION_SERVICE获得实例。
          */
        mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        imageView= (ImageView) findViewById(R.id.text_imageView);
        text_imageView2= (ImageView) findViewById(R.id.text_imageView2);
        // 开始
        Button startButton = (Button)findViewById(R.id.startButton);
        startButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                startProjection();
            }
        });

        // stop projection
        Button stopButton = (Button)findViewById(R.id.stopButton);
        stopButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                stopProjection();
            }
        });
        String mImageViewPath="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1503047905115&di=624821829abdf2761d3c276834a6366e&imgtype=0" +
                "&src=http%3A%2F%2Fwww.zhlzw.com%2FUploadFiles%2FArticle_UploadFiles%2F201204%2F20120412123914329.jpg";
//        mBitmap=ImageLoader.getInstance().loadImageSync(mImageViewPath);

        // start capture handling thread
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                mHandler = new Handler();
                Looper.loop();
            }
        }.start();
    }


    /**
     * 设置图片
     */
    private boolean mFlag=false;
    private void setImageview(){
        boolean isSdCardExist = Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED);// 判断sdcard是否存在
        if (isSdCardExist) {
           // textView1.setText("sd卡是存在的。以下是sdcard下的img25.jpg!");File.separator
            String filepath = STORE_DIRECTORY +"/myscreen_" + IMAGES_PRODUCED + ".png";
            File file = new File(filepath);
            if (file.exists()) {
                Bitmap bm = BitmapFactory.decodeFile(filepath);
                // 将图片显示到ImageView中


                /**
                 * 这里使用BitmapFactory.decodeStream(InputStream is);方法加载图片可以有效的防止
                 * 当内存过大时出现内存溢出的情况
                 */

                if (mFlag=true){
                    imageView.setImageBitmap(bm);
                }


            }
        } else {
           // textView1.setText("sd卡不存在!");
        }
    }

    /**
     * 截图成功保存成bitmap
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
        @Override
        public void onImageAvailable(ImageReader reader) {
            Image image = null;
            FileOutputStream fos = null;
            Bitmap bitmap = null;

            try {
                image = mImageReader.acquireLatestImage();
                if (image != null) {
                    Image.Plane[] planes = image.getPlanes();
                    ByteBuffer buffer = planes[0].getBuffer();
                    int pixelStride = planes[0].getPixelStride();
                    int rowStride = planes[0].getRowStride();
                    int rowPadding = rowStride - pixelStride * mWidth;

                    bitmap=takeScreenShot(TestActivity.this,mWidth + rowPadding / pixelStride);//修改的
                    // create bitmap原来的
                    //bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
                    bitmap.copyPixelsFromBuffer(buffer);

                    // write bitmap to a file
                    fos = new FileOutputStream(STORE_DIRECTORY + "/myscreen_" + IMAGES_PRODUCED + ".png");
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                    stopProjection();
                    //IMAGES_PRODUCED++;
                    Log.e(TAG, "captured image: " + IMAGES_PRODUCED);
                    mHandlerWolder.sendEmptyMessage(1);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fos!=null) {
                    try {
                        fos.close();
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
                }

                if (bitmap!=null) {
                    bitmap.recycle();
                }

                if (image!=null) {
                    image.close();
                }
            }
        }

    }

    /**
     * 去掉标题栏
     */
    public static Bitmap takeScreenShot(Activity activity, int mWidth) {
        // View是你需要截图的View
        View view = activity.getWindow().getDecorView();
        // view.setDrawingCacheEnabled(true);
        view.setDrawingCacheEnabled(false);
        view.buildDrawingCache();
        Bitmap b1 = view.getDrawingCache();

        // 获取状态栏高度
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;

        // 获取屏幕长和高
        int width = activity.getWindowManager().getDefaultDisplay().getWidth();
        int height = activity.getWindowManager().getDefaultDisplay()
                .getHeight();
        //用bitmap的高度,不用屏幕的高度,不然有可能报错,因为有的手机(魅族手机)底部有占高度
        height=b1.getHeight();
        // 去掉标题栏
        // Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);
        Bitmap b = Bitmap.createBitmap(mWidth, height-statusBarHeight-100, Bitmap.Config.ARGB_8888);
        view.destroyDrawingCache();
        return b;
    }

    private class OrientationChangeCallback extends OrientationEventListener {
        public OrientationChangeCallback(Context context) {
            super(context);
        }

        @TargetApi(Build.VERSION_CODES.KITKAT)
        @Override
        public void onOrientationChanged(int orientation) {
            synchronized (this) {
                final int rotation = mDisplay.getRotation();
                if (rotation != mRotation) {
                    mRotation = rotation;
                    try {
                        // clean up
                        if(mVirtualDisplay != null) mVirtualDisplay.release();
                        if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);

                        // re-create virtual display depending on device width / height
                        createVirtualDisplay();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 截屏改变方向
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private class MediaProjectionStopCallback extends MediaProjection.Callback {
        @Override
        public void onStop() {
            Log.e("ScreenCapture", "stopping projection.");
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if(mVirtualDisplay != null) mVirtualDisplay.release();
                    if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);
                    if(mOrientationChangeCallback != null) mOrientationChangeCallback.disable();
                    sMediaProjection.unregisterCallback(MediaProjectionStopCallback.this);
                }
            });
        }
    }


    /**
     * 如果授权成功,通过MediaProjectionManager.getMediaProjection(int resultCode, Intent resultData)
     * 获取MediaProjection实例,通过MediaProjection.createVirtualDisplay(String name, int width, int height, int dpi, int flags, Surface surface,
     * VirtualDisplay.Callback callback, Handler handler)
     * 创建VirtualDisplay实例。实际上在上述方法中传入的surface参数,是真正用来截屏或者录屏的。
     * @param data
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE) {
            sMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);//主要的类获取这个类

            if (sMediaProjection != null) {
                STORE_DIRECTORY = Environment.getExternalStorageDirectory().getAbsolutePath() + "/screenshots/";//内存卡地址
                File storeDirectory = new File(STORE_DIRECTORY);
                if (!storeDirectory.exists()) {
                    boolean success = storeDirectory.mkdirs();
                    if(!success) {
                        Log.e(TAG, "failed to create file storage directory.");
                        return;
                    }else {
                        Log.e(TAG,"成功");
                    }
                }

                //获取屏幕大小等
                DisplayMetrics metrics = getResources().getDisplayMetrics();
                mDensity = metrics.densityDpi;
                mDisplay = getWindowManager().getDefaultDisplay();

                //设置宽高
                createVirtualDisplay();

                /**
                 *截屏顺序,改变回调
                 */
                mOrientationChangeCallback = new OrientationChangeCallback(this);
                if (mOrientationChangeCallback.canDetectOrientation()) {
                    mOrientationChangeCallback.enable();
                }

                // 截屏开始,注册回调接口
                sMediaProjection.registerCallback(new MediaProjectionStopCallback(), mHandler);
            }
        }
    }

    /**
     * 第二部
     * 接着调用MediaProjectionManager.createScreenCaptureIntent()弹出dialog询问用户是否授权应用捕捉屏幕,
     * 同时覆写onActivityResult()获取授权结果
     * **/
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void startProjection() {
        startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
    }

    /**
     * 停止
     */
    private void stopProjection() {
        mHandler.post(new Runnable() {
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void run() {
                if (sMediaProjection != null) {
                    sMediaProjection.stop();
                }
            }
        });
    }
    /**
     * 宽高显示截屏大小
     * 截屏这里用到ImageReader类,这个类的getSurface()方法获取到surface直接传入MediaProjection.createVirtualDisplay()方法中,
     * 此时就可以执行截取。通过ImageReader.acquireLatestImage()方法即可获取当前屏幕的Image,经过简单处理之后即可保存为Bitmap。
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void createVirtualDisplay() {
        // get width and height
        Point size = new Point();
        mDisplay.getSize(size);
        mWidth = size.x;
        mHeight = size.y;
        //创建截取类
        mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);
        //编译器
        mVirtualDisplay = sMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight, mDensity, VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, mHandler);
        //回调
        mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);
    }
}

原文链接:http://www.apkbus.com/blog-340477-72625.html

0人推荐
随时随地看视频
慕课网APP