Android camera preview in surfaceview
17,815
Solution 1
I am facing same problem but I got this preview size by this method and now my camera preview working properly.
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) h / w;
if (sizes == null)
return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
double ratio = (double) size.height / size.width;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
}
Solution 2
You have a choice to start "startPreview" inside a different thread ..
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(80, 60);
camera.setParameters(parameters);
Thread preview_thread = new Thread(new Runnable() {
@Override
public void run() {
camera.startPreview();
}
}, "preview_thread");
preview_thread.start();
}
Author by
Mihael Meklav
Updated on June 04, 2022Comments
-
Mihael Meklav almost 2 years
I manage to put camera preview in surfaceview and this works great. But now i have problem with speed of other components. Because now it is really slow.
Do i need to put camera in new thread? How to decrease fps or resolution? Because this what i have now does not work properly.
My surface view:
class KameraSurface extends SurfaceView implements SurfaceHolder.Callback { private static final String TAG = "Preview"; SurfaceHolder mHolder; public Camera camera; KameraSurface(Context context) { super(context); // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. mHolder = getHolder(); mHolder.addCallback(this); mHolder.setFormat(PixelFormat.RGB_332); mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU); } public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, acquire the camera and tell it where // to draw. camera = Camera.open(); Camera.Parameters p = camera.getParameters(); p.setPictureSize(80, 60); p.setColorEffect(android.hardware.Camera.Parameters.EFFECT_NONE); p.setJpegQuality(20); p.setPreviewFrameRate(1); p.setPreviewFpsRange(5, 10); p.setPreviewSize(80, 60); camera.setParameters(p); try { camera.setPreviewDisplay(holder); camera.setPreviewCallback(new PreviewCallback() { public void onPreviewFrame(byte[] data, Camera arg1) { //KameraSurface.this.invalidate(); } }); } catch (IOException e) { e.printStackTrace(); } } public void surfaceDestroyed(SurfaceHolder holder) { // Surface will be destroyed when we return, so stop the preview. // Because the CameraDevice object is not a shared resource, it's very // important to release it when the activity is paused. camera.stopPreview(); camera = null; } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // Now that the size is known, set up the camera parameters and begin // the preview. Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(80, 60); camera.setParameters(parameters); camera.startPreview(); } @Override public void draw(Canvas canvas) { super.draw(canvas); Paint p= new Paint(Color.RED); Log.d(TAG,"draw"); canvas.drawText("PREVIEW", canvas.getWidth()/2, canvas.getHeight()/2, p ); } }
My xml:
. . . <TableRow android:layout_width="match_parent" android:layout_height="fill_parent" > <FrameLayout android:id="@+id/preview" android:layout_width="133dp" android:layout_height="100dp" android:layout_margin="20dp" > </FrameLayout> . . .
And how i call in main activity:
KameraSurface preview = new KameraSurface(getApplicationContext()); ((FrameLayout) findViewById(R.id.preview)).addView(preview);
-
Alex Cohn almost 8 years
-
-
Daud Arfin over 11 yearswhy you have set frame rate as 1 .... standard frame rate for any camera device is atleast 15 fps ... try the same ..
-
Mihael Meklav over 11 yearsBut there is no need to have 15fps.
-
Mihael Meklav over 11 yearsOn goclever a103 tablet (ICS)
-
Graham Smith over 11 yearsHave you enabled Hardware acceleration? developer.android.com/guide/topics/graphics/hardware-accel.html <application android:hardwareAccelerated="true" ...>
-
Mihael Meklav over 11 yearsI think that now is a little bit faster... Other half is probably because of a cheep tablet.
-
Graham Smith over 11 yearsTry running it on BlueStacks, the video playback is the only thing that doesnt work well but it links to your webcam to do camera work. Try it on there to see if is better. bluestacks.com