在安卓系统中,如何对SurfaceView进行截屏?

11

我正在使用以下方法来截取特定视图(SurfaceView)的屏幕截图。

public void takeScreenShot(View surface_view){

    // create bitmap screen capture
    Bitmap bitmap;
    View v1 = surface_view;
    v1.setDrawingCacheEnabled(true);
    bitmap = Bitmap.createBitmap(v1.getDrawingCache());
    v1.setDrawingCacheEnabled(false);

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(CompressFormat.PNG, 0, bos);
    byte[] imageData = bos.toByteArray();

}

问题在于它给了我整个活动屏幕的图像。但我需要截取特定视图的屏幕截图。我尝试了其他方法,但那些给我黑屏截图,一些帖子说它需要rooted设备。有人能帮帮我吗?我需要这个解决方案。帮帮我....


3
你好,"the problem is its giving me the whole activity screen image"的意思是你能够捕捉整个界面和SurfaceView吗?我也遇到了同样的问题,但是使用了你提供的代码后,我仍然得到了整个Activity的截图,只是SurfaceView是黑色的框架。请问你能告诉我surface_view具体是什么吗? - ocramot
4个回答

2

SurfaceView是一个视图,但是在SurfaceView上的项目(如位图或其他对象)并不是任何视图。因此,在捕获SurfaceView时,它将捕获表面上的所有内容。您必须使用其他视图,如ImageView或其他覆盖在SurfaceView上的视图,然后捕获这些视图。

首先获取要拍摄图片的视图,然后执行以下操作

            Bitmap bitmap;
            View rv = **your view**
            rv.setDrawingCacheEnabled(true);
            bitmap = Bitmap.createBitmap(rv.getDrawingCache());
            rv.setDrawingCacheEnabled(false);

            // Write File to internal Storage

            String FILENAME = "captured.png";
            FileOutputStream fos = null;

            try {

                fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);

            } catch (FileNotFoundException e1) {

                e1.printStackTrace();
                Log.v("","FileNotFoundException: "+e1.getMessage());

            }

            try {
                bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
                fos.flush();
                fos.close();

            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 

我尝试用这种方式对SurfaceView进行截屏,但输出的位图宽度和高度为-1...我做错了什么? - Flash Thunder

0

使用这种方法对我来说很有效,实际上surfaceview不支持v1.setDrawingCacheEnabled(true); 我通过使用这段代码来解决问题。

 jpegCallback = new PictureCallback() {

        public void onPictureTaken(byte[] data, Camera camera) {

            camera.startPreview();
            Bitmap cameraBitmap = BitmapFactory.decodeByteArray
                    (data, 0, data.length);
            Matrix matrix = new Matrix();
            matrix.postRotate(90);
            pd = new ProgressDialog(MainActivity.this);
            pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            pd.setTitle("Wait!");
            pd.setMessage("capturing image.........");
            pd.setIndeterminate(false);
            pd.show();

            progressStatus = 0;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (progressStatus < 100) {
                        // Update the progress status
                        progressStatus += 1;

                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                // Update the progress status
                                pd.setProgress(progressStatus);
                                // If task execution completed
                                if (progressStatus == 100) {
                                    // Dismiss/hide the progress dialog
                                    pd.dismiss();
                                }
                            }
                        });
                    }
                }
            }).start();

            Bitmap rotatedBitmap = Bitmap.createBitmap(cameraBitmap, 0, 0, cameraBitmap.getWidth(), cameraBitmap.getHeight(), matrix, true);
            if (rotatedBitmap != null) {
                rotatedBitmap = combinebitmap(rotatedBitmap, bitmapMap);
                Random num = new Random();
                int nu = num.nextInt(1000);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
                byte[] bitmapdata = bos.toByteArray();
                ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
                String picId = String.valueOf(nu);
                String myfile = "Ghost" + picId + ".jpeg";
                File dir_image = new File(Environment.getExternalStorageDirectory() +//<---
                        File.separator + "LiveCamera");          //<---
                dir_image.mkdirs();                                                  //<---

                try {
                    File tmpFile = new File(dir_image, myfile);
                    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();
                    Toast.makeText(getApplicationContext(),
                            " Image saved at :LiveCamera", Toast.LENGTH_LONG).show();
                    camera.startPreview();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                MediaScannerConnection.scanFile(MainActivity.this,
                        new String[]{dir_image.toString()}, null,
                        new MediaScannerConnection.OnScanCompletedListener() {
                            public void onScanCompleted(String path, Uri uri) {
                            }
                        });


                safeToTakePicture = true;

            }

        }

    };

0

试着使用这个

Bitmap b = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);  
v.setDrawingCacheEnabled(false);            
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);

0

一旦您获取了位图,就可以像这样仅复制其中的一部分:

 private Bitmap copyBitmap(Bitmap src){

     //Copy the whole bitmap
     //Bitmap newBitmap = Bitmap.createBitmap(src);

     //Copy the center part only
     int w = src.getWidth();
     int h = src.getHeight();
     Bitmap newBitmap = Bitmap.createBitmap(src, w/4, h/4, w/2, h/2);

     return newBitmap;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接