简体   繁体   English

拍摄Android中的SurfaceView的屏幕截图

[英]Taking a screenshot of a SurfaceView in Android

I'm trying to take a screenshot of a SurfaceView, but it always results of a black screen. 我正在尝试拍摄SurfaceView的屏幕截图,但是它始终是黑屏的结果。 I've been searching but all the solutions I've found doesn't work to me. 我一直在搜索,但是找到的所有解决方案都对我不起作用。 This is my code. 这是我的代码。

This is the method I call to take the screenshot 这是我调用屏幕截图的方法

private void takePicture(){
        if(camera!=null) {
            camera.takePicture(null, null, jpgCb);
        }
    }

This is the jpg callback 这是jpg回调

jpgCb=new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(final byte[] data, final Camera camera) {
            btnAccept.setVisibility(View.VISIBLE);
            btnCancel.setVisibility(View.VISIBLE);
            btnFlash.setEnabled(false);

            btnAccept.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    stopCamera();
                    new AsyncTask<byte[], String, Void>() {
                        @Override
                        protected void onPreExecute() {
                            progressDialog=new ProgressDialog(CameraActivity.this);
                            progressDialog.setCancelable(false);
                            progressDialog.setTitle(getResources().getString(R.string.saving_process));
                            progressDialog.show();
                        }

                        @Override
                        protected void onProgressUpdate(String... values) {
                            progressDialog.setMessage(values[0]);
                        }

                        @Override
                        protected Void doInBackground(byte[]... params) {
                            byte[] data=params[0];

                            File fileDir=new File(Environment.getExternalStorageDirectory().getAbsolutePath() +File.separator+"folder"+File.separator+folderName);

                            if (!fileDir.exists())
                                fileDir.mkdirs();

                            File tmpFile=new File(fileDir,"tmpFile.jpeg");

                            try{
                                FileOutputStream fos=new FileOutputStream(tmpFile);
                                fos.write(data);
                                fos.close();
                            }catch (FileNotFoundException e){
                                Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_SHORT).show();
                            }catch (IOException e){
                                Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_SHORT).show();
                            }


                            BitmapFactory.Options options=new BitmapFactory.Options();
                            options.inPreferredConfig = Bitmap.Config.ARGB_8888;

                            tmpFile.delete();
                            takeScreenshot();

                            return null;
                        }

                        @Override
                        protected void onPostExecute(Void aVoid) {
                            super.onPostExecute(aVoid);

                            try{
                                pics=loadPics();
                                setGallery();
                            }catch (NullPointerException e){
                                e.printStackTrace();
                            }

                            Toast.makeText(getApplicationContext(),getResources().getString(R.string.image_saved),Toast.LENGTH_SHORT).show();

                            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
                                startCamera(w,h);
                            }else
                                startCamera();
                            btnAccept.setVisibility(View.GONE);
                            btnCancel.setVisibility(View.GONE);
                            btnFlash.setEnabled(true);
                            progressDialog.dismiss();
                        }
                    }.execute(data);
                }
            });

            btnCancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    stopCamera();
                    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
                        startCamera(w,h);
                    }else
                        startCamera();
                    btnAccept.setVisibility(View.GONE);
                    btnCancel.setVisibility(View.GONE);
                    btnFlash.setEnabled(true);
                }
            });
        }
    };

And this is the method I call in the callback that really takes the screenshot 这是我在回调中调用的方法,该方法实际上截取了屏幕截图

public void takeScreenshot(){
    cameraContainer.setDrawingCacheEnabled(true);
    cameraContainer.buildDrawingCache(true);
    Bitmap bmp=Bitmap.createBitmap(cameraContainer.getDrawingCache());
    cameraContainer.setDrawingCacheEnabled(false);
    ByteArrayOutputStream bos=new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG,qualityValue,bos);
    byte[] bitmapData=bos.toByteArray();
    ByteArrayInputStream fis=new ByteArrayInputStream(bitmapData);

    String fileName=System.currentTimeMillis()+".jpeg";
    File fileDir=new File(Environment.getExternalStorageDirectory().getAbsolutePath() +File.separator+"folder"+File.separator+folderName);

    if (!fileDir.exists())
        fileDir.mkdirs();

    try{
        File tmpFile=new File(fileDir,fileName);
        FileOutputStream fos=new FileOutputStream(tmpFile);

        byte[] buf=new byte[1024];
        int len;
        while ((len=fis.read(buf))>0) {
            fos.write(buf, 0, len);
        }
        fis.close();
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

With this I'm able to save the "SurfaceView content" in a file and store it, but the content is a fully black screen. 这样,我可以将“ SurfaceView内容”保存在文件中并存储,但是内容是全黑屏幕。

PS: This is the question I most find when trying to solve my problem (indeed, the 'takeScreenshot' method is from that answer) PS:这是我在尝试解决问题时最容易发现的问题(实际上,“ takeScreenshot”方法来自该答案)

EDIT: This is the stopCamera method 编辑:这是stopCamera方法

private void stopCamera(){
    camera.setPreviewCallback(null);
    camera.stopPreview();
    camera.release();
    camera=null;
}

Well, after you shut down your camera, i'd expect the camera to not show anything anymore, so the surface should be empty, means black. 好吧,关闭相机后,我希望相机不再显示任何内容,因此表面应该是空的,即黑色。

What do you want to achieve, anyway? 无论如何,您想实现什么? You already got your photo saved to a file already, didn't you? 您已经将照片保存到文件中,不是吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM