我想做的是,在SurfaceView
打开相机的活动中,并在其中进行预览。点击一个按钮后,SurfaceView
停止/不可见,因此图像捕获将显示在活动中ImageView
。
如下图所示:
所以我有一个自定义相机活动,其中包含如下所示的XML,
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/showImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
<FloatingActionButton
android:id="@+id/cameraButton"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true" />
</FrameLayout>
我想要做的是,当我点击浮动按钮时,SurfaceView
消失,ImageView
可见,然后ImageView
上显示的相机拍摄的图像。
所以我到目前为止尝试了
public class CameraActivity extends AppCompatActivity implements
SurfaceHolder.Callback {
Camera mCamera;
Camera.PictureCallback jpegCallback;
ImageView showImage;
FloatingActionButton btnCamera;
SurfaceHolder surfaceHolder;
SurfaceView surfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
btnCamera = (FloatingActionButton) findViewById(R.id.cameraButton);
surfaceView = (SurfaceView)findViewById(R.id.surface_view);
showImage = (ImageView)findViewById(R.id.showImage);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
btnCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//here when click the camera button
//camera take photo
//surface view disappear
//preview image shown on image view
mCamera.takePicture(null,null,jpegCallback);
showImage.setVisibility(View.VISIBLE);
surfaceView.setVisibility(View.INVISIBLE);
}
});
jpegCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outputStream = null;
File file_image = getDirs();
if(!file_image.exists() && !file_image.mkdirs()){
Toast.makeText(getApplicationContext(),"Failed to save picture",Toast.LENGTH_LONG).show();
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
String date = simpleDateFormat.format(new Date());
String photofile = "myphotos" + date+ ".jpg";
String file_name = file_image.getAbsolutePath() + "/" + photofile;
File picFile = new File(file_name);
Bitmap bitmap = null;
try{
outputStream = new FileOutputStream(picFile);
outputStream.write(data);
outputStream.close();
//here set the picture capture to the image view
//convert it to bitmap,setBitmap to the imageView
bitmap = decodeFile(picFile,10);
if(bitmap !=null){
showImage.setImageBitmap(bitmap);
Toast.makeText(CameraActivity.this,
"Picture Captured Successfully:", Toast.LENGTH_LONG)
.show();
}else {
Toast.makeText(CameraActivity.this,
"Failed to Capture the picture. kindly Try Again:",
Toast.LENGTH_LONG).show();
}
} catch (IOException e){
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),"Picture saved",Toast.LENGTH_LONG).show();
refreshCamera();
}
};
}
private void refreshCamera() {
if(surfaceHolder.getSurface() == null){
return;
}
//stop the camera preview
try{
mCamera.stopPreview();
}catch (Exception e){
e.printStackTrace();
}
//start camera again
try{
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//open camera
try{
mCamera = Camera.open();
}catch (RuntimeException ex){
ex.printStackTrace();
}
Camera.Parameters parameters;
parameters = mCamera.getParameters();
parameters.setPreviewFrameRate(20);
parameters.setPreviewSize(352,288);
mCamera.setParameters(parameters);
mCamera.setDisplayOrientation(90);
try{
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refreshCamera();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera= null;
}
}
尝试此操作后,我现在得到的是,屏幕完全空白。SurfaceView
是不可见的,ImageView
预览从相机中取出的图像未显示出来。
但我检查了file_name
,bitmap
在日志中有值。
所以我尝试过,不要将SurfaceView
设置为隐身,如下所示:
btnCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cameraImage();
showImage.setVisibility(View.VISIBLE);
//surfaceView.setVisibility(View.INVISIBLE);
}
});
图像可以显示在表面视图的顶部,如下所示,但如果我将表面视图设置为不可见,则整个屏幕显示为空白。
但我希望表面视图消失,只有ImageView可用。
答案 0 :(得分:0)
移动以下行(使表面视图不可见),
surfaceView.setVisibility(View.INVISIBLE);
从onClick(View v)
方法到onPictureTaken(byte[] data, Camera camera)
方法可以解决问题。
但是,这会导致相机release
,并且必须再次打开以拍摄另一张照片。