boofcv.android.camera.CameraPreview Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boofcv-android Show documentation
Show all versions of boofcv-android Show documentation
BoofCV is an open source Java library for real-time computer vision and robotics applications.
/*
* Copyright (c) 2011-2017, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.android.camera;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import java.io.IOException;
/**
* Displays camera preview. Android forces the camera preview to be displayed at all times. This gets
* around that restriction by making the preview to be 2x2 pixel big .
*
* @author Peter Abeles
*/
public class CameraPreview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "CameraPreview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Camera mCamera;
Camera.PreviewCallback previewCallback;
boolean hidden;
public CameraPreview(Context context, Camera.PreviewCallback previewCallback, boolean hidden ) {
super(context);
this.previewCallback = previewCallback;
this.hidden = hidden;
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
// We purposely disregard child measurements so that the SurfaceView will center the camera
// preview instead of stretching it.
startPreview();
// Need to adjust the layout for the new camera
requestLayout();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if( hidden ) {
this.setMeasuredDimension(2, 2);
} else {
// We purposely disregard child measurements because want it to act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if( mCamera == null )
return;
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
Camera.Size size = mCamera.getParameters().getPreviewSize();
int previewWidth = size.width;
int previewHeight = size.height;
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
l = (width - scaledChildWidth) / 2;
t = 0;
r = (width + scaledChildWidth) / 2;
b = height;
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
l = 0;
t = (height - scaledChildHeight) / 2;
r = width;
b = (height + scaledChildHeight) / 2;
}
child.layout(l,t,r,b);
// Log.w("BoofCV","onLayout did stuff");
} else {
// Log.w("BoofCV","onLayout nothing done");
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.stopPreview();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if( mCamera == null )
return;
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// start preview with new settings
startPreview();
}
private void startPreview() {
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
} catch (Exception e){
Log.e(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy