SurfaceView 的截屏

Capture screen of SurfaceView

在上图中,我有一个 SurfaceView 和一个名为 CaptureButtonSurfaceView 正在显示相机预览。所以,当我点击 Capture 按钮时,我想要 surfaceview 的屏幕截图。我尝试了很多示例和答案,但其中 none 有效。我刚得到 黑色屏幕截图图像

在一些帖子中我也发现无法对surfaceview进行截图。所以请用例子帮助我任何替代解决方案。

以下是我已经看到的一些答案:

how to create and save a screenshot from a surfaceview?

Taking screenshot programmatically doesnt capture the contents of surfaceVIew

How to capture screenshot of surfaceview with background

还有很多。

这是我的activity呼叫代码:

public class CamView extends Activity implements SurfaceHolder.Callback {

    protected static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;

    private SurfaceView SurView;

    private SurfaceHolder camHolder;

    private boolean previewRunning;

    final Context context = this;

    public static Camera camera = null;

    private RelativeLayout CamView;

    private Bitmap bmp1;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cam_view);

        CamView = (RelativeLayout) findViewById(R.id.camview);
        SurView = (SurfaceView) findViewById(R.id.sview);
        camHolder = SurView.getHolder();
        camHolder.addCallback(this);
        camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        Button btn = (Button) findViewById(R.id.button1);

        btn.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                camera.takePicture(null, null, mPicture);
            }
        });
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (previewRunning) {
            camera.stopPreview();
        }
        Camera.Parameters camParams = camera.getParameters();
        Camera.Size size = camParams.getSupportedPreviewSizes().get(0);
        camParams.setPreviewSize(size.width, size.height);
        camera.setParameters(camParams);
        try {
            camera.setPreviewDisplay(holder);
            camera.startPreview();
            previewRunning = true;
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {
        try {
            camera = Camera.open();
        }
        catch (Exception e) {
            e.printStackTrace();
            finish();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        camera.release();
        camera = null;
    }

    public void TakeScreenshot() {
        Random num = new Random();
        int nu = num.nextInt(1000);
        CamView.setDrawingCacheEnabled(true);
        CamView.buildDrawingCache(true);
        Bitmap bmp = Bitmap.createBitmap(CamView.getDrawingCache());
        CamView.setDrawingCacheEnabled(false);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bmp.compress(CompressFormat.JPEG, 100, bos);
        byte[] bitmapdata = bos.toByteArray();
        ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);

        String picId = String.valueOf(nu);
        String myfile = "anand" + picId + ".jpeg";

        File dir_image = new File(Environment.getExternalStorageDirectory() + File.separator + "anand");
        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();
            bmp1 = null;

            camera.startPreview();
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    private PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            File dir_image2 = new File(Environment.getExternalStorageDirectory() + File.separator + "anand");
            dir_image2.mkdirs();
            File tmpFile = new File(dir_image2, "TempPic.jpg");
            try {
                FileOutputStream fos = new FileOutputStream(tmpFile);
                fos.write(data);
                fos.close();
            }
            catch (FileNotFoundException e) {
            }
            catch (IOException e) {
            }

            String path = (Environment.getExternalStorageDirectory() + File.separator + "anand" + File.separator + "TempPic.jpg");

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
            bmp1 = BitmapFactory.decodeFile(path, options);

            tmpFile.delete();
            TakeScreenshot();
        }
    };

    public Bitmap decodeFile(File f) {
        Bitmap b = null;
        try {
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;

            FileInputStream fis = new FileInputStream(f);
            BitmapFactory.decodeStream(fis, null, o);
            fis.close();
            int IMAGE_MAX_SIZE = 1000;
            int scale = 1;
            if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
                scale = (int) Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
            }

            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            fis = new FileInputStream(f);
            b = BitmapFactory.decodeStream(fis, null, o2);
            fis.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return b;
    }
}

这是我的布局代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"   
android:id="@+id/camview">

<SurfaceView
    android:id="@+id/sview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" />

<Button
    android:id="@+id/button1"
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" />


</RelativeLayout>

我用来拍照的代码;

buttonClick = (Button) findViewById(R.id.btnBasicCamTakePic);
buttonClick.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        preview.camera.takePicture(shutterCallback, rawCallback,jpegCallback);
    }
});

    ShutterCallback shutterCallback = new ShutterCallback() {
        public void onShutter() {
            Log.d(TAG, "onShutter'd");
        }
    };

    /** Handles data for raw picture */
    PictureCallback rawCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            Log.d(TAG, "onPictureTaken - raw");
        }
    };

    /** Handles data for jpeg picture */
    PictureCallback jpegCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {

            File myExternalFile = new File(BasicCam.this.getExternalFilesDir("/MyFileStorage/qrscans/"), fileName);
            myExternalFile.delete();
            myExternalFile.createNewFile();
            FileOutputStream output = new FileOutputStream(myExternalFile);
            output.write(data2);
            output.flush();
            output.close();             
        }
    });