Show android camera preview on half screen in application - android

I am developing an application in which user sees its own camera preview in half screen and other half screen is a static picture
i used intent but it will show preview in fullscreen.
is there any way possible to do it?

Use 2 fragments to populate your UI, each taking half the screen - apply a surface view to the bottom one and use that to display real time camera data - and use the other fragment how you want.
Quick anaswer because i am at work :)

try this:
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout" android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="match_parent" >
<SurfaceView android:id="#+id/surfaceView" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_weight="1" />
<ImageView android:id="#+id/imageView1" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_weight="1" />
</LinearLayout>
Main.java:
setContentView(R.layout.main);
preview = new Preview(this, (SurfaceView)findViewById(R.id.surfaceView));
preview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
((LinearLayout) findViewById(R.id.layout)).addView(preview);
Preview.java:
class Preview extends ViewGroup implements SurfaceHolder.Callback {
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
Preview(Context context, SurfaceView sv) {
super(context);
mSurfaceView = sv;
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
Camera.Parameters params = mCamera.getParameters();
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
mCamera.setParameters(params);
}
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null)
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2, width, (height + scaledChildHeight) / 2);
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
try {
if (mCamera != null) mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
Log.e("AWAISSOOMRO_TAG", "IOException caused by setPreviewDisplay()", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) mCamera.stopPreview();
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
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 (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mCamera != null) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
}
SOURCE: https://github.com/josnidhin/Android-Camera-Example

Related

Multiscreen Support in android : Camera preview is stretched in Samsung Galaxy s4 mini issue android

This is my Preview class to take a picture : it's working perfectly with many devices but Android Samsung Galaxy S4 shows me bad result => the problem that the image is stretched when preview.
You can see the image below :
Here is my code :
class Preview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Camera.Size mPreviewSize;
List<Camera.Size> mSupportedPreviewSizes;
Camera mCamera;
Preview(Context context, SurfaceView sv) {
super(context);
mSurfaceView = sv;
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
// get Camera parameters
Camera.Parameters params = mCamera.getParameters();
List<String> focusModes = params.getSupportedFocusModes();
try {
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
} else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_INFINITY)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
}
mCamera.setParameters(params);
}
catch (Exception e) {
}
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because 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);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
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);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.stopPreview();
}
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
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;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if(mCamera != null) {
if (mPreviewSize!=null){
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
}
}
I want to keep image support Multiscreen in android after preview.
To not have a stretched image or preview , you should choose a previewSize that keep the same ratio as the screen of the phone. Then , you should set it before launching and starting the camera. Try this code :
public void setCamera(Camera camera, int screenW, int screenH) {
//screenW ==> screen width of the phone in Pixels
//screenH ==> screen height of the phone in Pixels
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, screenW
, screenH);
}
requestLayout();
// get Camera parameters
Camera.Parameters params = mCamera.getParameters();
if (mPreviewSize != null)
params.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
List<String> focusModes = params.getSupportedFocusModes();
try {
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
} else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
} else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_INFINITY)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
}
mCamera.setParameters(params);
Log.i(TAG, " getPreviewSize " + mCamera.getParameters().getPreviewSize().width + " X "
+ mCamera.getParameters().getPreviewSize().height);
Log.i(TAG, " getPictureSize " + mCamera.getParameters().getPictureSize().width + " X "
+ mCamera.getParameters().getPictureSize().height);
} catch (Exception e) {
}
}
}

How to change Surface View Height in Xamarin.Android?

My layout code.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:showIn="#layout/Main">
<LinearLayout
android:id="#+id/camera_ll"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:weightSum="100"
android:orientation="vertical">
<FrameLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:id="#+id/frameLayout"
android:layout_weight="90" />
<Button
android:layout_height="0dp"
android:layout_width="match_parent"
android:id="#+id/btn_capture"
android:text="Scan Answer Sheet"
fontPath="Fonts/Verb-Semibold.otf"
android:textColor="#android:color/white"
android:background="#drawable/bttn_green"
android:layout_weight="10" />
</LinearLayout>
</RelativeLayout>
My Java code is this.
public class CameraPreview : Activity, Android.Hardware.Camera.IPictureCallback, Android.Hardware.Camera.IPreviewCallback, Android.Hardware.Camera.IShutterCallback
{
String PICTURE_FILENAME = "picture.jpg";
Preview mPreview;
Camera mCamera;
int numberOfCameras;
int cameraCurrentlyLocked;
// The first rear facing camera
int defaultCameraId;
FrameLayout frameLayout;
Button btn_capture;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Hide the window title and go fullscreen.
RequestWindowFeature(WindowFeatures.NoTitle);
Window.AddFlags(WindowManagerFlags.Fullscreen);
// Create our Preview view and set it as the content of our activity.
SetContentView(Resource.Layout.CameraPriview);
frameLayout = FindViewById<FrameLayout>(Resource.Id.frameLayout);
btn_capture = FindViewById<Button>(Resource.Id.btn_capture);
mPreview = new Preview(this, frameLayout);
frameLayout.AddView(mPreview);
btn_capture.Click += TakeAPicture;
// Find the total number of cameras available
numberOfCameras = Camera.NumberOfCameras;
// Find the ID of the default camera
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < numberOfCameras; i++)
{
Camera.GetCameraInfo(i, cameraInfo);
if (cameraInfo.Facing == CameraFacing.Back)
{
defaultCameraId = i;
}
}
}
private void TakeAPicture(object sender, EventArgs eventArgs)
{
Android.Hardware.Camera.Parameters p = mCamera.GetParameters();
p.PictureFormat = Android.Graphics.ImageFormatType.Jpeg;
mCamera.SetParameters(p);
mCamera.TakePicture(this, this, this);
}
void Camera.IPictureCallback.OnPictureTaken(byte[] data, Android.Hardware.Camera camera)
{
FileOutputStream outStream = null;
File dataDir = Android.OS.Environment.ExternalStorageDirectory;
if (data != null)
{
try
{
outStream = new FileOutputStream(dataDir + "/" + PICTURE_FILENAME);
outStream.Write(data);
outStream.Close();
}
catch (FileNotFoundException e)
{
System.Console.Out.WriteLine(e.Message);
}
catch (IOException ie)
{
System.Console.Out.WriteLine(ie.Message);
}
}
}
void Camera.IPreviewCallback.OnPreviewFrame(byte[] b, Android.Hardware.Camera c)
{
}
void Camera.IShutterCallback.OnShutter()
{
}
protected override void OnResume()
{
base.OnResume();
// Open the default i.e. the first rear facing camera.
mCamera = Camera.Open();
cameraCurrentlyLocked = defaultCameraId;
mPreview.PreviewCamera = mCamera;
mCamera.SetDisplayOrientation(90);
}
protected override void OnPause()
{
base.OnPause();
// Because the Camera object is a shared resource, it's very
// important to release it when the activity is paused.
if (mCamera != null)
{
mPreview.PreviewCamera = null;
mCamera.Release();
mCamera = null;
}
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
// Inflate our menu which can gather user input for switching camera
//MenuInflater.Inflate(Resource.Menu.camera_menu, menu);
return true;
}
}
Surface View Code.
class Preview : ViewGroup, ISurfaceHolderCallback
{
string TAG = "Preview";
FrameLayout f;
SurfaceView mSurfaceView;
ISurfaceHolder mHolder;
Camera.Size mPreviewSize;
IList<Camera.Size> mSupportedPreviewSizes;
Camera _camera;
public Camera PreviewCamera
{
get { return _camera; }
set
{
_camera = value;
if (_camera != null)
{
mSupportedPreviewSizes = PreviewCamera.GetParameters().SupportedPreviewSizes;
RequestLayout();
}
}
}
public Preview(Context context, FrameLayout f) : base(context)
{
this.f = f;
mSurfaceView = new SurfaceView(context);
AddView(mSurfaceView);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.Holder;
mHolder.AddCallback(this);
mHolder.SetType(SurfaceType.PushBuffers);
}
public void SwitchCamera(Camera camera)
{
PreviewCamera = camera;
try
{
camera.SetPreviewDisplay(mHolder);
}
catch (Java.IO.IOException exception)
{
Log.Error(TAG, "IOException caused by setPreviewDisplay()", exception);
}
Camera.Parameters parameters = camera.GetParameters();
parameters.SetPreviewSize(mPreviewSize.Width, mPreviewSize.Height);
RequestLayout();
camera.SetParameters(parameters);
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
int width = ResolveSize(SuggestedMinimumWidth, widthMeasureSpec);
int height = ResolveSize(SuggestedMinimumHeight, heightMeasureSpec);
SetMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null)
{
mPreviewSize = GetOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
if (changed && ChildCount > 0)
{
View child = GetChildAt(0);
int width = r - l;
int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null)
{
previewWidth = mPreviewSize.Width;
previewHeight = mPreviewSize.Height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth)
{
int scaledChildWidth = previewWidth * height / previewHeight;
child.Layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
}
else
{
int scaledChildHeight = previewHeight * width / previewWidth;
child.Layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
public void SurfaceCreated(ISurfaceHolder holder)
{
// The Surface has been created, acquire the camera and tell it where
// to draw.
try
{
if (PreviewCamera != null)
{
PreviewCamera.SetPreviewDisplay(holder);
}
}
catch (Java.IO.IOException exception)
{
Log.Error(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
// Surface will be destroyed when we return, so stop the preview.
if (PreviewCamera != null)
{
PreviewCamera.StopPreview();
}
}
private Camera.Size GetOptimalPreviewSize(IList<Camera.Size> sizes, int w, int h)
{
const double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double)w / h;
if (sizes == null)
return null;
Camera.Size optimalSize = null;
double minDiff = Double.MaxValue;
int targetHeight = h;
// Try to find an size match aspect ratio and size
foreach (Camera.Size size in sizes)
{
double ratio = (double)size.Width / size.Height;
if (Math.Abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.Abs(size.Height - targetHeight) < minDiff)
{
optimalSize = size;
minDiff = Math.Abs(size.Height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null)
{
minDiff = Double.MaxValue;
foreach (Camera.Size size in sizes)
{
if (Math.Abs(size.Height - targetHeight) < minDiff)
{
optimalSize = size;
minDiff = Math.Abs(size.Height - targetHeight);
}
}
}
return optimalSize;
}
public void SurfaceChanged(ISurfaceHolder holder, Android.Graphics.Format format, int w, int h)
{
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = PreviewCamera.GetParameters();
parameters.SetPreviewSize(mPreviewSize.Width, mPreviewSize.Height);
RequestLayout();
PreviewCamera.SetParameters(parameters);
PreviewCamera.StartPreview();
}
}
Output:
Now i want to increase the camera height to fill all available space but nothing working for me. If anyone know the solution please help thanks.
Now i want to increase the camera height to fill all available space but nothing working for me. If anyone know the solution please help thanks.
The setting codes of the preview Size lies in Preview's OnLayout method:
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
if (changed && ChildCount > 0)
{
View child = GetChildAt(0);
int width = r - l;
int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null)
{
previewWidth = mPreviewSize.Width;
previewHeight = mPreviewSize.Height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth)
{
int scaledChildWidth = previewWidth * height / previewHeight;
child.Layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
}
else
{
int scaledChildHeight = previewHeight * width / previewWidth;
child.Layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
Here I don't get the codes' meaning. But by child.Layout(0, (height - scaledChildHeight) / 2,width, (height + scaledChildHeight) / 2);, you are decreasing the top boundary and bottom boundary of the preview window to (height - scaledChildHeight) / 2 and (height + scaledChildHeight) / 2).
So to to increase the camera height to fill all available space you need to modify this code snippet.
For Example:
int LeftBoundary=0,TopBoundary=0;
int RightBoundary=r,BottomBoundary=b;
child.Layout(LeftBoundary,TopBoundary,RightBoundary,BottomBoundary));

Zbar Android Costum Camera Preview Stretched

I customize the camera view of Zbar API in ZBarScannerActivity class. This is the code i added.
setContentView(R.layout.scanner);
mAutoFocusHandler = new Handler();
// Create and configure the ImageScanner;
setupScanner();
// Create a RelativeLayout container that will hold a SurfaceView,
// and set it as the content of our activity.
mPreview = new CameraPreview(this, this, autoFocusCB);
LinearLayout zbarLayout = (LinearLayout) findViewById(R.id.zbar_layout_area);
mPreview.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
zbarLayout.addView(mPreview);
Then when i run the app the camera preview is wrong so i rotate it using setDisplayOrientation to 90. Then its already rotate but the camera view is stretched. This is my CameraPreview code.
private final String TAG = "CameraPreview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
PreviewCallback mPreviewCallback;
AutoFocusCallback mAutoFocusCallback;
CameraPreview(Context context, PreviewCallback previewCallback, AutoFocusCallback autoFocusCb) {
super(context);
mPreviewCallback = previewCallback;
mAutoFocusCallback = autoFocusCb;
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) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because 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);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
public void hideSurfaceView() {
mSurfaceView.setVisibility(View.INVISIBLE);
}
public void showSurfaceView() {
mSurfaceView.setVisibility(View.VISIBLE);
}
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);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.cancelAutoFocus();
mCamera.stopPreview();
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
Log.d("Edgar", optimalSize.width + " " + optimalSize.height);
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (holder.getSurface() == null){
// preview surface does not exist
return;
}
if (mCamera != null) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setDisplayOrientation(90);
mCamera.setParameters(parameters);
mCamera.setPreviewCallback(mPreviewCallback);
mCamera.startPreview();
mCamera.autoFocus(mAutoFocusCallback);
}
}
Please help me to fix the camera view. Thank you for helping.
If you are trying to do a view in portrait view, but basically show a landscape view portal that is not 'squished' then I would suggest doing a layout where the preview is behind your other layouts. Basically you could do
<RelativeLayout
android:layout_height="fill_parent"
android:layout_width="fill_parent"
>
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="#+id/ticket_overlay"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<... Some stuff here ... w/ background>
<... spacer here ... w/ transparent to show view portal>
<... Some stuff here ... w/ background>
</LinearLayout>
</FrameLayout>
</RelativeLayout>

Android custom camera issue in some devices

Hi, I have a custom camera where I have click button, when clicked it captures the image... Everything is fine but in some devices the preview is stretching and also the preview is overlaying half the screen and flickering... some wierd unwanted effect. How to fix this?
This is my code:
Camera Activity:
preview = new Preview(this, (SurfaceView) findViewById(R.id.surfaceView));
preview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
((FrameLayout) findViewById(R.id.preview)).addView(preview);
preview.setKeepScreenOn(true);
buttonClick = (Button) findViewById(R.id.buttonClick);
buttonClick.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
// camera.setDisplayOrientation(90);
}
});
Preview class:
class Preview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
#SuppressWarnings("deprecation")
Preview(Context context, SurfaceView sv) {
super(context);
mSurfaceView = sv;
// addView(mSurfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
// get Camera parameters
Camera.Parameters params = mCamera.getParameters();
mSupportedPreviewSizes = params.getSupportedPreviewSizes();
requestLayout();
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
mCamera.setParameters(params);
}
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because 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);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0, (width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2, width, (height + scaledChildHeight) / 2);
}
}
}
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);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.stopPreview();
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mCamera != null) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
}
There is a known bug happening on some devices for the image captures described here:
https://code.google.com/p/android/issues/detail?id=1480
Not sure if your problem is the same, but you should try the code explained in this answer from another question:
https://stackoverflow.com/a/1932268/2206688
McAfee Antivirus may be the culprit in this case.
In which case, uninstalling it should solve the issue.

in android, stream camera preview onto a view

I want to stream the camera preview of the android camera, onto a view. The intention is to afterwards add various things to the view, using onDraw(). I don't need to actually capture the image at any time.
It doesn't have to be in the highest quality or largest number of frames per second.
Does anyone have an idea how this can be done?
add this to your xml:
<SurfaceView
android:id="#+id/camerapreview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
into your activity-class:
private Preview mPreview;
Camera mCamera;
int numberOfCameras;
int cameraCurrentlyLocked;
int defaultCameraId;
onCreate-Method:
mPreview = new Preview(this);
setContentView(mPreview);
mPreview.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mCamera.autoFocus(null);
}
});
#Override
protected void onPause() {
super.onPause();
// Because the Camera object is a shared resource, it's very
// important to release it when the activity is paused.
if (mCamera != null) {
mPreview.setCamera(null);
mCamera.release();
mCamera = null;
}
}
#Override
protected void onResume() {
super.onResume();
// Open the default i.e. the first rear facing camera.
mCamera = Camera.open();
cameraCurrentlyLocked = defaultCameraId;
mPreview.setCamera(mCamera);
}
and the preview-class:
public class Preview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
public Preview(Context context) {
super(context);
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) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
}
}
public void switchCamera(Camera camera) {
setCamera(camera);
try {
camera.setPreviewDisplay(mHolder);
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
camera.setParameters(parameters);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because 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);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
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);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.stopPreview();
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
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.
if(mCamera != null){
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
}

Categories

Resources