我正在尝试实现一项功能,包括在录制视频时拍照。这就是我决定使用 SurfaceView 的屏幕截图方法的原因。
但是,当我尝试拍摄 SurfaceView 的屏幕截图时。我总是得到空白图像。
这是我用来拍摄快照的代码:
View tempView = (View)MY_SURFACE_VIEW;
tempView.setDrawingCacheEnabled(true);
Bitmap tempBmp = Bitmap.createBitmap(tempView.getDrawingCache());
tempView.setDrawingCacheEnabled(false);
//Saving this Bitmap to a File....
如果你们可能认为这是一个重复的问题,让我向你们保证,在提出这个问题之前,我已经尝试过针对同一问题在 SO 上提供的以下解决方案。
- https://stackoverflow.com/questions/24134964/issue-with-camera-picture-taken-snapshot-using-surfaceview-in-android
- Facing issue to take a screenshot while recording a video
- Take camera screenshot while recording - Like in Galaxy S3?
- Taking screen shot of a SurfaceView in android
- Get screenshot of surfaceView in Android (这是正确答案,但部分回答。我已经请@sajar 解释答案)
互联网上的其他资源:
1. http://www.coderanch.com/t/622613/Android/Mobile/capture-screenshot-simple-animation-project
2. http://www.phonesdevelopers.com/1795894/
到目前为止,这些都对我不起作用。我还知道我们需要创建一些与 Surface Holder 交互并从中获取位图的线程。但我不确定如何实现。
非常感谢任何帮助。
最佳答案
这是另一个:Take screenshot of SurfaceView .
SurfaceView 有一个“表面”部分和一个“ View ”部分;您的代码试图捕获“ View ”部分。 “表面”部分是一个单独的层,没有简单的“抓取所有像素”方法。基本困难在于您的应用程序位于表面的“生产者”端,而不是“消费者”端,因此读取像素是有问题的。请注意,底层缓冲区采用对数据生成器最方便的任何格式,因此对于相机预览,它将是 YUV 缓冲区。
“捕获”表面像素的最简单和最有效的方法是将它们绘制两次,一次用于屏幕,一次用于捕获。如果您使用 OpenGL ES 执行此操作,则 YUV 到 RGB 的转换可能会由硬件模块完成,这比在 YUV 缓冲区中接收相机帧并进行您自己的转换要快得多。
Grafika's “来自相机的纹理” Activity 演示了使用 GLES 处理传入的视频数据。渲染后,您可以使用 glReadPixels()
获取像素。 glReadPixels()
的性能在设备和不同用例之间可能会有很大差异。 EglSurfaceBase#saveFrame()
展示了如何捕获到 Bitmap
并另存为 PNG。
有关 Android 图形架构的更多信息,特别是 SurfaceView 表面的生产者-消费者性质,可以在 this document 中找到。 .
关于android - 使用相机预览截取 SurfaceView 的屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26293819/