I have the following java method:
private Camera openFrontFacingCameraGingerbread() {
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
cam = Camera.open(camIdx);
} catch (RuntimeException e) {
Toast.makeText(debug, "failed", Toast.LENGTH_LONG).show();
}
}
}
and what I'm looking forward to do is mirror the camera in the screen. This is, as soon as I open the app I would like the user to see himself but I'm not being able to accomplish this.
Here is the onCreate method of the same class:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
openFrontFacingCameraGingerbread();
}
Can someone help me on this one? Thank you very much
You need to include a SurfaceView in your layout, and use setPreviewDisplay() and startPreview(). This will draw the camera's input in your Activity.
You should check the developer guides, and also take a look at Android - Camera Preview
Related
Hi guys trying to implement AsyncTask here in my project, there seems to be no error shown by Android Studio either and have debugged to see if the bitmaps are downloaded and yes it is. I dont know what the problem is so here is my code.
My Activity:
public class MainActivity extends AppCompatActivity {
public ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView =findViewById(R.id.justAnImage);
String[] strings = new String[2];
strings[0] = "blah.com/sds.jpg";
strings[1] = "blah.com/sds2.jpg";
new AsyncDownloader(this,imageView).execute(strings);
}
public void StartAnimation(ImageView imageView, Bitmap[] bitmaps)
{
AnimationDrawable animation = new AnimationDrawable();
for (int i=0;i<bitmaps.length;i++) //replaced erroneous code-> (int i=0;i>=bitmaps.length;i++)
{
animation.addFrame(new BitmapDrawable(getApplicationContext().getResources(),bitmaps[i]),1000);
}
animation.setOneShot(false);
imageView.setBackground(animation);
// start the animation!
animation.start();
}
}
My Async downloader class
public class AsyncDownloader extends AsyncTask<String[],Void,Bitmap[]> {
private Bitmap[] bitmapArray;
private ImageView imageView;
MainActivity mainActivity;
public AsyncDownloader(MainActivity mainActivity,ImageView imageView) {
this.imageView = imageView;
bitmapArray = new Bitmap[2];
this.mainActivity = mainActivity;
}
#Override
protected Bitmap[] doInBackground(String[]... strings) {
for(int i=1;i>=0;i--)
{
try {
URL url = new URL(strings[0][i]);
bitmapArray[i] = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (Exception e) {
Log.e("DOWNLOAD ASYNC", e.getMessage());
}
}
return bitmapArray;
}
#Override
protected void onPostExecute(Bitmap[] bitmapArray) {
super.onPostExecute(bitmapArray);
//imageView.setImageBitmap(bitmapArray[0]);
mainActivity.StartAnimation(imageView,bitmapArray);
}
}
I cant find the problem here, debugging is so terrible in Android Studio. If any one could help, i shall be thankful.
EDIT 1: After suggestions from fellow stack guys, it is clear that the animation drawable is not working as desired and nonetheless there is no image showing up on the ImageView control.
EDIT 2: Code works after correcting the loop specified in the answer. Found an alternative to display images after certain interval. The code goes like this :
public void StartAnimation(final ImageView imageView, final Bitmap[] bitmaps)
{
handler = new Handler();
Runnable runnable = new Runnable() {
int i = 0;
public void run() {
imageView.setImageBitmap(bitmaps[i]);
i++;
if (i > bitmaps.length - 1) {
i = 0;
}
handler.postDelayed(this, 1200);
}
};
handler.postDelayed(runnable, 1200);
}
Your code is perfect, except loop condition inside method StartAnimation.
issue is with loop condition which is always false.
To fix the issue change
From
for (int i = 0; i >= bitmaps.length; i++)
To
for (int i = 0; i < bitmaps.length; i++)
use fresco or picosso or glide library
these libraries automatically caching and managing memory.
it's easy to work with picosso and glide but fresco adds more features to developers.
I need to implement few gestures in activity. I used Genymotion for that, saved gestures file in res/raw folder and wrote a code which is showing all good but keeps crashing the application. Does anyone know what could be the possible reason? I really tried to solve, but it seems i am missing something!
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GestureOverlayView gesturesView = new GestureOverlayView(this);
View inflate = getLayoutInflater().inflate(R.layout.activity_garden,
null);
gesturesView.addView(inflate);
gesturesView.addOnGesturePerformedListener(this);
gestures = GestureLibraries.fromRawResource(this, R.raw.gestures);
if (!gestures.load()) {
finish();
}
setContentView(gesturesView);
}
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = gestures.recognize(gesture);
int index = 0;
double maxScore = predictions.get(index).score;
for (int i = 1; i < predictions.size(); i++) {
if (predictions.get(i).score > maxScore) {
index = i;
maxScore = predictions.get(i).score;
}
}
Prediction p = predictions.get(index);
if (p.name.equalsIgnoreCase("Love"))
daisy.setImageResource(sp.getInt("Love", 0));
if (p.name.equalsIgnoreCase("Hit"))
daisy.setImageResource(sp.getInt("Hit", 0));
if (p.name.equalsIgnoreCase("Pet"))
daisy.setImageResource(sp.getInt("Pet", 0));
Toast.makeText(this, p.name + "\n" + p.score, Toast.LENGTH_SHORT)
.show();
}
On your code, what happen if you don't get any prediction?
Well, index will be equals to 0, and predictions.get(index) will crash because there is no object at index 0.
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = gestures.recognize(gesture);
if (predictions == null || predictions.isEmpty()) {
return;
}
// continue the regular flow
}
I'm using libgdx to make an application and I need to use the camera so I followed this tutorial and all my camera feed is rotated 90 degrees but they are being drawn as if they weren't. Unfortunately that means the preview is totally distorted and is very hard to use.
I won't post my code here unless snippets are asked for because I copy-pasted the code from the tutorial into my game.. The only change I recall making was as follows.
I changed the original surfaceCreated() method in CameraSurace.java
public void surfaceCreated( SurfaceHolder holder ) {
// Once the surface is created, simply open a handle to the camera hardware.
camera = Camera.open();
}
to open the front facing camera (Im using a Nexus 7 that only has a front camera...)
public void surfaceCreated( SurfaceHolder holder ) {
// Once the surface is created, simply open a handle to the camera hardware.
camera = openFrontFacingCamera();
}
#SuppressLint("NewApi")
private Camera openFrontFacingCamera()
{
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for ( int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
Camera.getCameraInfo( camIdx, cameraInfo );
if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ) {
try {
cam = Camera.open( camIdx );
} catch (RuntimeException e) {
System.out.println("Falied to open.");
}
}
}
return cam;
}
Other than that change the rest of the code is almost the exact same (excluding minor variable changes and such.)
You can use the ExifInterface class to determine the ORIENTATION_TAG associated with your image and rotate the image accordingly.
The code would look like this:
ei = new ExifInterface(imagePath);
orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
imageView.setRotation(90);
break;
...
default:
break;
}
Upon diving into the camera API, I found that all I have to do is use a nice little method called setDisplayOrientation(90) and it works perfectly now.
revised code:
#SuppressLint("NewApi")
public void surfaceCreated( SurfaceHolder holder ) {
// Once the surface is created, simply open a handle to the camera hardware.
camera = openFrontFacingCamera();
camera.setDisplayOrientation(90);
}
#SuppressLint("NewApi")
private Camera openFrontFacingCamera()
{
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for ( int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
Camera.getCameraInfo( camIdx, cameraInfo );
if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ) {
try {
cam = Camera.open( camIdx );
} catch (RuntimeException e) {
System.out.println("Falied to open.");
}
}
}
return cam;
}
P.S only reason I'm ignoring the NewApi is because I know the exact device this app will be running on, and it is specific to that device... Would not recommend unless you know that the device's API is high enough... (it only requires API 8)
New to Android programming here.
I have had a look around and have found this to be a common issue, but I don't really see an easy fix... I am trying to run the following code on a Nexus 7 (have tried AVD & physical device) with no luck whatsoever. It seems to be the:
camera.setPreviewDisplay(SurfaceHolder);
But I could be wrong. Here is the current code:
public class MainActivity extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cameralayout);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
}
public void onClick() {
// TODO Auto-generated method stub
if(!previewing){
camera = Camera.open();
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Any ideas folks? Thank you for your help!
From android documentation about Camera.open()
Creates a new Camera object to access the first back-facing camera on
the device. If the device does not have a back-facing camera, this
returns null.
It gives you only an access to back-facing Camera.
I am trying to run the following code on a Nexus 7
Camera.open() returns null because Nexus 7 doesn't have a back camera, only a front camera.
You could try this method
public Camera getCamera()
{
for(int i = 0; i < Camera.getNumberOfCameras(); i++)
return Camera.open(i);
return null;
}
To apply,
camera = getCamera();
I have seen lots of tutorial and information but i could not find any single place how to use the default settings of the existing camera application into any other customized camera application. I have seen the sharpness of the image and its focus is very fine in the built-in camera application. Now i am creating my own application with my customized features but i am still unable to make it sharp and non-blurry... I dont want to use Intent technique of the camera because i have to do some image processing afterward.
I have used zooming but strangely zoom is not properly working ...like it works in built-in camera application
here is my surface change code
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
Log.e(TAG, "surfaceChanged");
// XXX stopPreview() will crash if preview is not running
if (mPreviewRunning) {
mCamera.stopPreview();
}
Camera.Parameters params = mCamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
mFrameWidth = w;
mFrameHeight = h;
// selecting optimal camera preview size
{
double minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes)
{
if (Math.abs(size.height - h) < minDiff)
{
mFrameWidth = size.width;
mFrameHeight = size.height;
minDiff = Math.abs(size.height - h);
}
}
}
try
{
//params.set("rotation", 180);
//params.set("orientation", "landscape");
//params.set("auto", "WHITE_BALANCE_AUTO");//WHITE_BALANCE_AUTO
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0)
{
params.setPreviewSize(mFrameHeight, mFrameWidth);
mCamera.setDisplayOrientation(90);
}
if(display.getRotation() == Surface.ROTATION_90)
{
params.setPreviewSize(mFrameWidth, mFrameHeight);
}
if(display.getRotation() == Surface.ROTATION_180)
{
params.setPreviewSize(mFrameHeight, mFrameWidth);
}
if(display.getRotation() == Surface.ROTATION_270)
{
params.setPreviewSize(mFrameWidth, mFrameHeight);
mCamera.setDisplayOrientation(180);
}
if(params.isZoomSupported())
{
Log.e(TAG, params.getZoom()+"surfaceChanged camer zoom"+params.getMinExposureCompensation());
params.setZoom(params.getMaxZoom());
params.setExposureCompensation(1);
// params.setColorEffect("none");
params.setWhiteBalance(params.WHITE_BALANCE_AUTO);
params.setFocusMode(params.FOCUS_MODE_AUTO);
params.setSceneMode(params.SCENE_MODE_ACTION);
}
params.set("auto", "FOCUS_MODE_AUTO");
params.setPreviewSize(mFrameWidth,mFrameHeight);
mCamera.setParameters(params);
mCamera.setPreviewDisplay(holder);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
}
Kindly let me know how to make the camera preview exactly same as the built in application one.
You mean a fullscreen camera preview?
I use this code:
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //no title
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //no status bar, etc
and this:
setContentView(R.layout.main);
addContentView(overlay, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
((FrameLayout) findViewById(R.id.preview)).addView(preview);
the first snippet sets the app to fullscreen and hide title and status bar.
the second snipppet adds my overlay (extended View) to the main layout.
Here my xml and java code:
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/preview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</LinearLayout>
Overlay.java:
class Overlay extends View {
String text = "";
String textBearing = "Bearing: ";
public Overlay(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setTextSize(16);
canvas.drawText(text, 20, 20, paint);
canvas.drawText(textBearing, 20, 50, paint);
super.onDraw(canvas);
}
}
And my activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //no title
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //fullscreen
overlay = new Overlay(this);
setContentView(R.layout.main);
addContentView(overlay, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
camera = getCameraInstance(); //camera.open();
preview = new Preview(this, camera);
((FrameLayout) findViewById(R.id.preview)).addView(preview);
}
Hope it helps
I encountered the same problem with you. After reading the source code of the builtin camera app, and comparing the focus processing of builtin camera and my own camera, I realized the problem is on autofocus.
So try this:
mCamera.autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
mCamera.takePicture(null, null, mPicture);
}
});
which makes the result image as sharp as builtin camera.
The documents is here.