inthy
inthy

Reputation: 382

camera.startPreview() is too slow

I want to make a camera app, that starts showing the image from camera to screen while button is pushed and takes photo when button is released. I've done everything, but the camera start speed is too slow. I want it to start immediately when I push the button. I've tried to instantiate my camera, set all the parameters and stream it an invisible SurfaceView, but it seems like it relaunches camera, when I push the button. what can be the problem?

Here is my code:

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;    
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.SeekBar;
import android.view.View;
import android.graphics.AvoidXfermode.Mode;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.json.JSONException;
import org.json.JSONObject;

import com.shtern.selfy.MainActivity.JSONParse;

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class CameraActivity extends Activity implements SurfaceHolder.Callback,
    View.OnTouchListener, Camera.PictureCallback, Camera.PreviewCallback {
private Camera camera;
private SurfaceHolder surfaceHolder;
private SurfaceView preview;
private Button shotBtn;
JSONObject json = new JSONObject();
JSONParse jsparse = new JSONParse();
String url = "http://myserverurl";
String userid;
String token;
String parentactivity;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    userid = getIntent().getStringExtra("userid").toString();
    token = getIntent().getStringExtra("token").toString();
    parentactivity = getIntent().getStringExtra("parent").toString();


    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);


    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);


    requestWindowFeature(Window.FEATURE_NO_TITLE);

    setContentView(R.layout.camera);


    preview = (SurfaceView) findViewById(R.id.SurfaceView01);

    surfaceHolder = preview.getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


    shotBtn = (Button) findViewById(R.id.Button01);
    shotBtn.setOnTouchListener(this);
    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
    // camera = Camera.open();
    Camera.Parameters params = camera.getParameters();
    params.setPictureSize(800, 480);
    params.setRotation(270);
    camera.setParameters(params);
    try {
        camera.setPreviewDisplay(surfaceHolder);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        camera.setPreviewDisplay(surfaceHolder);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    preview.setVisibility(View.VISIBLE);
    camera.startPreview();
    preview.setVisibility(View.VISIBLE);


}

@Override
protected void onResume() {
    super.onResume();

    preview.setVisibility(View.INVISIBLE);
}

@Override
protected void onPause() {
    super.onPause();

    if (camera != null) {
        camera.stopPreview();
        camera.setPreviewCallback(null);

        camera.release();
        camera = null;
    }
    preview.setVisibility(View.GONE);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    Log.d("SURFACE", "CREATED");

    Size previewSize = camera.getParameters().getPreviewSize();
    float aspect = (float) previewSize.width / previewSize.height;

    int previewSurfaceWidth = preview.getWidth();
    int previewSurfaceHeight = preview.getHeight();

    LayoutParams lp = preview.getLayoutParams();

    if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {


        camera.setDisplayOrientation(90);
        lp.height = previewSurfaceHeight;
        lp.width = (int) (previewSurfaceHeight / aspect);

    } else {


        camera.setDisplayOrientation(0);
        lp.width = previewSurfaceWidth;
        lp.height = (int) (previewSurfaceWidth / aspect);
    }

    preview.setLayoutParams(lp);

    try {
        camera.setPreviewDisplay(holder);
        camera.setPreviewCallback(this);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    camera.stopPreview();
    camera.setPreviewCallback(null);
    camera.release();
    camera = null;
    preview.setVisibility(View.GONE);
}

public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        Log.d("TOUCH", "PUSHED");
        shotBtn.setVisibility(View.GONE);
        preview.setVisibility(View.VISIBLE);

        // start_camera();

    }
    if (event.getAction() == MotionEvent.ACTION_UP) {
        Log.d("TOUCH", "Release detected");

        camera.takePicture(null, null, null, this);
        //

    }
    return true;
}

@Override
public void onPictureTaken(byte[] paramArrayOfByte, Camera paramCamera) {
    camera.stopPreview();
    camera.setPreviewCallback(null);
    preview.setVisibility(View.INVISIBLE);
    CameraActivity.this.finish();
    FrameLayout fl = (FrameLayout) findViewById(R.id.FrameLayout01);
    fl.removeAllViews();
    try {
        String path = CameraActivity.this.getFilesDir().getPath();
        Log.d("PATH", path);
        File saveDir = new File(path);

        if (!saveDir.exists()) {
            saveDir.mkdirs();
        }
        FileOutputStream os = new FileOutputStream(String.format(path
                + "/ava.jpg"));

        os.write(paramArrayOfByte);
        os.close();
    } catch (Exception e) {
    }


    jsparse.execute();

}

class JSONParse extends AsyncTask<Void, Void, JSONObject> {

    @Override
    protected JSONObject doInBackground(Void... params) {

        List<NameValuePair> parameters = new ArrayList<NameValuePair>();
        String path = CameraActivity.this.getFilesDir().getPath();
        path = path + "/ava.jpg";
        Log.d("PATHINCAMERA", path);

        parameters.add(new BasicNameValuePair("user_id", userid));
        parameters.add(new BasicNameValuePair("token", token));
        parameters.add(new BasicNameValuePair("file", path));
        url = url + "/change_avatar_request/";

        postWithImage(url, parameters);
        if (parentactivity.equals("RegisterActivity")) {
            final Intent intent = new Intent(getApplicationContext(),
                    MenuActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.putExtra("userid", String.valueOf(userid));
            intent.putExtra("token", String.valueOf(token));
            startActivity(intent);
        }
        // CameraActivity.this.finish();
        return null;
    }

    @Override
    protected void onPostExecute(JSONObject json) {


    }

}

public void postWithImage(String url, List<NameValuePair> nameValuePairs) {
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpPost httpPost = new HttpPost(url);

    try {
        MultipartEntity entity = new MultipartEntity(
                HttpMultipartMode.BROWSER_COMPATIBLE);

        for (int index = 0; index < nameValuePairs.size(); index++) {
            if (nameValuePairs.get(index).getName()
                    .equalsIgnoreCase("file")) {
                // If the key equals to "image", we use FileBody to transfer
                // the data
                entity.addPart(nameValuePairs.get(index).getName(),
                        new FileBody(new File(nameValuePairs.get(index)
                                .getValue())));
            } else {
                // Normal string data
                entity.addPart(
                        nameValuePairs.get(index).getName(),
                        new StringBody(nameValuePairs.get(index).getValue()));
            }
        }

        httpPost.setEntity(entity);

        HttpResponse response = httpClient.execute(httpPost, localContext);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void onPreviewFrame(byte[] paramArrayOfByte, Camera paramCamera) {

}
}

Upvotes: 2

Views: 2757

Answers (2)

devcelebi
devcelebi

Reputation: 887

if you want to set image to imageview,maybe you can this code.You can look this project

PictureCallback jpegCallback = new PictureCallback() {
    @SuppressWarnings("deprecation")
    public void onPictureTaken(byte[] data, Camera camera) {

        Bitmap realImage;
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 5;
        options.inPurgeable=true;  
        options.inInputShareable=true;     
        realImage = BitmapFactory.decodeByteArray(data,0,data.length,options);

        image.setImageBitmap(realImage);

    }

Upvotes: 0

Alex Cohn
Alex Cohn

Reputation: 57163

To keep preview working, you should not set

preview.setVisibility(View.INVISIBLE)

Instead, you can temporarily (until the button is pressed) cover the preview with non-transparent view, e.g. ImageView.

Upvotes: 1

Related Questions