在android中使用surfaceview在应用程序中使用相机 [英] Using camera inside an app using surfaceview in android

查看:192
本文介绍了在android中使用surfaceview在应用程序中使用相机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个应用程序,我可以在其中使用相机,而无需使用默认的手机应用程序。所以我已经使用了一个表面视图,并尝试将其保存到手机上,但是 onPictureTaken 永远不会被调用。完整的代码如下所示:

  package com.example.surfaceviewcamera; 

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements SurfaceHolder.Callback {

SurfaceView mSurfaceView;
SurfaceHolder mSurfaceHolder;
相机mCamera;
boolean mPreviewRunning;
按钮btncapture;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btncapture =(Button)findViewById(R.id.btncapture);
mSurfaceView =(SurfaceView)findViewById(R.id.surface_camera);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

btncapture.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v){
Camera.PictureCallback mPictureCallback = new Camera .PictureCallback(){
public void onPictureTaken(byte [] imageData,Camera c){

位图位图= BitmapFactory.decodeByteArray(imageData,0,imageData .length);
String file_path = saveToInternalSorage(bitmap);
Toast.makeText(getApplicationContext(),Image成功存储在+ file_path,Toast.LENGTH_LONG).show();
}

};

}
});

}
private String saveToInternalSorage(Bitmap bitmapImage){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
//路径到/ data / data / yourapp / app_data / imageDir
文件目录= cw.getDir(imageDir,Context.MODE_PRIVATE);
//创建imageDir
文件mypath =新文件(目录,marina1.jpg);

FileOutputStream fos = null;
try {

fos = new FileOutputStream(mypath);

//使用BitMap对象上的compress方法将图像写入OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG,100,fos);
fos.close();
} catch(Exception e){
e.printStackTrace();
}
return directory.getAbsolutePath();
}
@Override
public void surfaceCreated(SurfaceHolder holder){
mCamera = Camera.open();


}

@Override
public void surfaceChanged(SurfaceHolder holder,int format,int w,
int h){
if(mPreviewRunning){
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(w,h);
mCamera.setParameters(p);
try {
mCamera.setPreviewDisplay(holder);
} catch(IOException e){
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;

}


@Override
public void surfaceDestroyed(SurfaceHolder holder){
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();

}

}

我的XML文件:

 < LinearLayout xmlns:android =http://schemas.android.com/apk/res/android
android:layout_width =fill_parent
android:layout_height =fill_parent
android:orientation =vertical>

< SurfaceView
android:id =@ + id / surface_camera
android:layout_width =fill_parent
android:layout_height =10dip
android:layout_weight =1>
< / SurfaceView>
< Button
android:layout_width =wrap_content
android:layout_height =wrap_content
android:text =CAPTURE IMAGE
android:id = @ + id / btncapture
android:layout_gravity =center
/>
< / LinearLayout>


解决方案

调用 camera.takePicture null,null,callback); from onClick()并定义 onCreate()



供参考查看此链接

  public class MainActivity extends Activity implements SurfaceHolder.Callback { 

SurfaceView mSurfaceView;
SurfaceHolder mSurfaceHolder;
相机mCamera;
boolean mPreviewRunning;
按钮btncapture;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btncapture =(Button)findViewById(R.id.btncapture);
mSurfaceView =(SurfaceView)findViewById(R.id.surface_camera);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

btncapture.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v){
//在这里拍照
mCamera.takePicture(null,null,mPictureCallback);
}
});
}

Camera.PictureCallback mPictureCallback = new Camera.PictureCallback(){
public void onPictureTaken(byte [] imageData,Camera c){

Bitmap Bitmap = BitmapFactory.decodeByteArray(imageData,0,imageData .length);
String file_path = saveToInternalSorage(bitmap);
Toast.makeText(getApplicationContext(),成功存储在+ file_path,Toast.LENGTH_LONG).show();
}
};

private String saveToInternalSorage(Bitmap bitmapImage){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
//路径到/ data / data / yourapp / app_data / imageDir
文件目录= cw.getDir(imageDir,Context.MODE_PRIVATE);
//创建imageDir
文件mypath =新文件(目录,marina1.jpg);

FileOutputStream fos = null;
try {

fos = new FileOutputStream(mypath);

//使用BitMap对象上的compress方法将图像写入OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG,100,fos);
fos.close();
} catch(Exception e){
e.printStackTrace();
}
return directory.getAbsolutePath();
}
@Override
public void surfaceCreated(SurfaceHolder holder){
mCamera = Camera.open();


}

@Override
public void surfaceChanged(SurfaceHolder holder,int format,int w,
int h){
if(mPreviewRunning){
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(w,h);
mCamera.setParameters(p);
try {
mCamera.setPreviewDisplay(holder);
} catch(IOException e){
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;

}


@Override
public void surfaceDestroyed(SurfaceHolder holder){
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();

}

}


I am creating an app where i can use the camera inside it without going to the default app of the phone.So i have used a surface view and tried to save it onto the phone, but the onPictureTaken never gets called.The complete code is shown below:

package com.example.surfaceviewcamera;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements SurfaceHolder.Callback {

    SurfaceView mSurfaceView;
    SurfaceHolder mSurfaceHolder;
    Camera mCamera;
    boolean mPreviewRunning;
    Button btncapture;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btncapture=(Button) findViewById(R.id.btncapture);
        mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        btncapture.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
                    public void onPictureTaken(byte[] imageData, Camera c) {

                        Bitmap bitmap = BitmapFactory.decodeByteArray(imageData , 0, imageData .length);
                        String file_path=saveToInternalSorage(bitmap);
                        Toast.makeText(getApplicationContext(),"Image stored succesfully at "+file_path,Toast.LENGTH_LONG).show();
                    }

                    };

            }
        });

    }
    private String saveToInternalSorage(Bitmap bitmapImage){
        ContextWrapper cw = new ContextWrapper(getApplicationContext());
         // path to /data/data/yourapp/app_data/imageDir
        File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
        // Create imageDir
        File mypath=new File(directory,"marina1.jpg");

        FileOutputStream fos = null;
        try {           

            fos = new FileOutputStream(mypath);

       // Use the compress method on the BitMap object to write image to the OutputStream
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return directory.getAbsolutePath();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mCamera=Camera.open();


    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int w,
            int h) {
        if (mPreviewRunning) {
            mCamera.stopPreview();
            }
            Camera.Parameters p = mCamera.getParameters();
            p.setPreviewSize(w, h);
            mCamera.setParameters(p);
            try {
            mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
            e.printStackTrace();
            }
            mCamera.startPreview();
            mPreviewRunning = true;

    }


    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mCamera.stopPreview();
        mPreviewRunning = false;
        mCamera.release();

    }

}

My XML file:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
 android:layout_height="fill_parent"
android:orientation="vertical">

<SurfaceView
 android:id="@+id/surface_camera"
android:layout_width="fill_parent"
 android:layout_height="10dip"
android:layout_weight="1">
</SurfaceView>
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="CAPTURE IMAGE"
    android:id="@+id/btncapture"
    android:layout_gravity="center"
    />
</LinearLayout>

解决方案

call camera.takePicture(null, null, callback); from onClick() and define the callback outside the onCreate()

for reference look into this link

public class MainActivity extends Activity implements SurfaceHolder.Callback {

    SurfaceView mSurfaceView;
    SurfaceHolder mSurfaceHolder;
    Camera mCamera;
    boolean mPreviewRunning;
    Button btncapture;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btncapture=(Button) findViewById(R.id.btncapture);
        mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        btncapture.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //take picture here
                mCamera.takePicture(null, null, mPictureCallback);
            }
        });
    }

    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] imageData, Camera c) {

            Bitmap bitmap = BitmapFactory.decodeByteArray(imageData , 0, imageData .length);
            String file_path=saveToInternalSorage(bitmap);
            Toast.makeText(getApplicationContext(),"Image stored succesfully at "+file_path,Toast.LENGTH_LONG).show();
        }
    };

    private String saveToInternalSorage(Bitmap bitmapImage){
        ContextWrapper cw = new ContextWrapper(getApplicationContext());
         // path to /data/data/yourapp/app_data/imageDir
        File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
        // Create imageDir
        File mypath=new File(directory,"marina1.jpg");

        FileOutputStream fos = null;
        try {           

            fos = new FileOutputStream(mypath);

       // Use the compress method on the BitMap object to write image to the OutputStream
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return directory.getAbsolutePath();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mCamera=Camera.open();


    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int w,
            int h) {
        if (mPreviewRunning) {
            mCamera.stopPreview();
            }
            Camera.Parameters p = mCamera.getParameters();
            p.setPreviewSize(w, h);
            mCamera.setParameters(p);
            try {
            mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
            e.printStackTrace();
            }
            mCamera.startPreview();
            mPreviewRunning = true;

    }


    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mCamera.stopPreview();
        mPreviewRunning = false;
        mCamera.release();

    }

}

这篇关于在android中使用surfaceview在应用程序中使用相机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆