SurfaceView的捕获屏幕 [英] Capture screen of SurfaceView
问题描述
在上图中我有一个 SurfaceView
和一个按钮
名为拍摄
。 SurfaceView
正显示出相机preVIEW。所以,我想 surfaceview
当我在点击捕获
按钮的屏幕截图。我试过很多例子和答案,但他们没有工作。我刚刚得到的黑色屏幕截图图片。
在一些帖子我还发现这是不可能采取 surfaceview
的屏幕截图。所以,请帮我看看诸如任何替代解决方案。
下面是一些答案我已经看到了:
<一个href=\"http://stackoverflow.com/questions/25091703/how-to-create-and-save-a-screenshot-from-a-surfaceview\">how创建并从surfaceview保存截图?
<一个href=\"http://stackoverflow.com/questions/18289544/taking-screenshot-programmatically-doesnt-capture-the-contents-of-surfaceview\">Taking截图编程犯规捕捉surfaceVIew 的内容
<一个href=\"http://stackoverflow.com/questions/11505093/how-to-capture-screenshot-of-surfaceview-with-background\">How捕捉背景 surfaceview的截图
等等。
这是我的电话活动code:
公共类CamView扩展活动实现SurfaceHolder.Callback { 受保护的静态最终诠释CAPTURE_IMAGE_ACTIVITY_REQUEST_ code = 0; 私人SurfaceView SurView; 私人SurfaceHolder camHolder; 私人布尔previewRunning; 最后上下文的背景下=这; 公共静态摄像头摄像头= NULL; 私人的RelativeLayout CamView; 私人位图BMP1; @燮pressWarnings(德precation)
@覆盖
保护无效的onCreate(捆绑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(本);
camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 按钮BTN =(按钮)findViewById(R.id.button1); btn.setOnClickListener(新OnClickListener(){
公共无效的onClick(视图v){
camera.takePicture(NULL,NULL,mPicture);
}
});
} @覆盖
公共无效surfaceChanged(SurfaceHolder架,INT格式,诠释的宽度,高度INT){
如果(previewRunning){
camera.stop preVIEW();
}
Camera.Parameters camParams = camera.getParameters();
Camera.Size大小= camParams.getSupported previewSizes()得到(0);
camParams.set previewSize(size.width,size.height);
camera.setParameters(camParams);
尝试{
camera.set previewDisplay(支架);
camera.start preVIEW();
previewRunning = TRUE;
}
赶上(IOException异常五){
e.printStackTrace();
}
} 公共无效surfaceCreated(SurfaceHolder持有人){
尝试{
相机= Camera.open();
}
赶上(例外五){
e.printStackTrace();
完();
}
} @覆盖
公共无效surfaceDestroyed(SurfaceHolder持有人){
camera.stop preVIEW();
camera.release();
摄像头= NULL;
} 公共无效TakeScreenshot(){
随机数,=新的随机();
INT NU = num.nextInt(1000);
CamView.setDrawingCacheEnabled(真);
CamView.buildDrawingCache(真);
BMP位图= Bitmap.createBitmap(CamView.getDrawingCache());
CamView.setDrawingCacheEnabled(假);
ByteArrayOutputStream BOS =新ByteArrayOutputStream();
bmp.com preSS(比较pressFormat.JPEG,100,BOS);
字节[] =的BitmapData bos.toByteArray();
ByteArrayInputStream的FIS =新ByteArrayInputStream进行(的BitmapData); 字符串picId =将String.valueOf(NU);
字符串MYFILE =阿南+ picId +.JPEG 文件dir_image =新的文件(Environment.getExternalStorageDirectory()+文件分割符+阿南);
dir_image.mkdirs();
尝试{
文件TMPFILE =新的文件(dir_image,MYFILE);
FOS的FileOutputStream =新的FileOutputStream(TMPFILE); 字节[] buf中=新的字节[1024];
INT LEN;
而((LEN = fis.read(BUF))大于0){
fos.write(BUF,0,LEN);
}
fis.close();
fos.close();
BMP1 = NULL; camera.start preVIEW();
}
赶上(FileNotFoundException异常五){
e.printStackTrace();
}
赶上(IOException异常五){
e.printStackTrace();
}
} 私人PictureCallback mPicture =新PictureCallback(){
@覆盖
公共无效onPictureTaken(字节[]数据,相机摄像头){ 文件dir_image2 =新的文件(Environment.getExternalStorageDirectory()+文件分割符+阿南);
dir_image2.mkdirs();
文件TMPFILE =新的文件(dir_image2TempPic.jpg);
尝试{
FOS的FileOutputStream =新的FileOutputStream(TMPFILE);
fos.write(数据);
fos.close();
}
赶上(FileNotFoundException异常五){
}
赶上(IOException异常五){
} 字符串路径=(Environment.getExternalStorageDirectory()+文件分割符+阿南+文件分割符+TempPic.jpg); BitmapFactory.Options选项=新BitmapFactory.Options();
options.in preferredConfig = Bitmap.Config.ARGB_8888;
BMP1 = BitmapFactory.de codeFILE(路径选择); tmpFile.delete();
TakeScreenshot();
}
}; 公共位图德codeFILE(文件f){
位图B = NULL;
尝试{
BitmapFactory.Options O =新BitmapFactory.Options();
o.inJustDe codeBounds = TRUE; FIS的FileInputStream =新的FileInputStream(F);
BitmapFactory.de codeStream(FIS,空,O);
fis.close();
INT IMAGE_MAX_SIZE = 1000;
int标= 1;
如果(o.outHeight&GT; IMAGE_MAX_SIZE || o.outWidth&GT; IMAGE_MAX_SIZE){
比例=(int)的Math.pow(2,(int)的Math.round(将Math.log(IMAGE_MAX_SIZE /(双)Math.max(o.outHeight,o.outWidth))/将Math.log(0.5)));
} BitmapFactory.Options O2 =新BitmapFactory.Options();
o2.inSampleSize =规模;
FIS =新的FileInputStream(F);
B = BitmapFactory.de codeStream(FIS,空,O2);
fis.close();
}
赶上(IOException异常五){
e.printStackTrace();
}
返回b;
}
}
这是我的布局code:
&LT;?XML版本=1.0编码=UTF-8&GT?;
&LT;的RelativeLayout的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:ID =@ + ID / camview&GT;&LT; SurfaceView
机器人:ID =@ + ID / sview
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:layout_alignParentLeft =真
机器人:layout_alignParentTop =真/&GT;&LT;按钮
机器人:ID =@ + ID /按钮1
风格=机器人:ATTR / buttonStyleSmall
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:layout_alignParentLeft =真
机器人:layout_alignParentTop =真/&GT;
&LT; / RelativeLayout的&GT;
在code我用它来拍摄一张照片;
buttonClick =(按钮)findViewById(R.id.btnBasicCamTakePic);
buttonClick.setOnClickListener(新OnClickListener(){
公共无效的onClick(视图v){
preview.camera.takePicture(shutterCallback,rawCallback,jpegCallback);
}
}); ShutterCallback shutterCallback =新ShutterCallback(){
公共无效onShutter(){
Log.d(TAGonShutter'd);
}
}; / **处理数据为原料的图片* /
PictureCallback rawCallback =新PictureCallback(){
公共无效onPictureTaken(字节[]数据,相机摄像头){
Log.d(TAGonPictureTaken - 原始);
}
}; / **处理数据为JPEG图片* /
PictureCallback jpegCallback =新PictureCallback(){
公共无效onPictureTaken(字节[]数据,相机摄像头){ 文件myExternalFile =新的文件(BasicCam.this.getExternalFilesDir(/ MyFileStorage / qrscans /),文件名);
myExternalFile.delete();
myExternalFile.createNewFile();
FileOutputStream中输出=新的FileOutputStream(myExternalFile);
output.write(数据2);
output.flush();
output.close();
}
});
In above image i have one SurfaceView
and one Button
named Capture
. SurfaceView
is showing camera preview. So, I want screenshot of surfaceview
when i click on Capture
button. I had tried many examples and answers but none of them works. I just get Black Screenshot image.
In some posts i also found it is impossible to take screenshot of surfaceview
. So please help me any alternative solution with example.
Here are some answers I already seen:
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
and many more.
This is my activity call code:
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;
}
}
This is my layout code:
<?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>
The code i use to capture a picture;
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();
}
});
这篇关于SurfaceView的捕获屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!