Search code examples
javaandroidandroid-intentgoogle-vision

Passing a Camera Intent to Android Input Stream


I am working on an Android Activity where I want to pass a Camera Intent to an Input Stream, in order to process it further through the Activity; The aim is that the user can make a Camera picture and that the picture is then processed as an Input Stream and passed to an API.

I am not sure if that´s the best way to "convert" a Camera Image into an Input Stream, therefore I am open to any suggestion and hint; this is my code so far:

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.api.client.extensions.android.json.AndroidJsonFactory;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.services.vision.v1.Vision;
import com.google.api.services.vision.v1.VisionRequestInitializer;
import com.google.api.services.vision.v1.model.AnnotateImageRequest;
import com.google.api.services.vision.v1.model.BatchAnnotateImagesRequest;
import com.google.api.services.vision.v1.model.BatchAnnotateImagesResponse;
import com.google.api.services.vision.v1.model.FaceAnnotation;
import com.google.api.services.vision.v1.model.Feature;
import com.google.api.services.vision.v1.model.Image;

import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

import static java.nio.channels.Pipe.open;

public class VisionAPIActivity extends AppCompatActivity {

    ImageView imgFavorite;
    public final static int CAMERA_REQUEST = 1888;

    public void TakePicture() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(takePictureIntent, CAMERA_REQUEST);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TakePicture();
        setContentView(R.layout.activity_vision_api);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });





        Vision.Builder visionBuilder = new Vision.Builder(
                new NetHttpTransport(),
                new AndroidJsonFactory(),
                null);

        visionBuilder.setVisionRequestInitializer(
                new VisionRequestInitializer("AIzaSyCnPwvnEQakkUXpkFaj2TcwJs_E3DPqjm0"));
        final Vision vision = visionBuilder.build();

        Log.i("log-", "passed VisionBuilder Initialisation");

        // Create new thread
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                // Convert photo to byte array
                final InputStream inputStream =
                        getResources().openRawResource(R.raw.skate);
                byte[] photoData = new byte[0];
                Log.i("log-", "Content of Photo Data" + photoData);

                try {
                    photoData = IOUtils.toByteArray(inputStream);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Image inputImage = new Image();
                inputImage.encodeContent(photoData);
                Feature desiredFeature = new Feature();
                desiredFeature.setType("FACE_DETECTION");
                AnnotateImageRequest request = new AnnotateImageRequest();
                request.setImage(inputImage);
                Log.i("log-", "Content of inputImage" + inputImage);
                request.setFeatures(Arrays.asList(desiredFeature));
                BatchAnnotateImagesRequest batchRequest =
                        new BatchAnnotateImagesRequest();

                batchRequest.setRequests(Arrays.asList(request));
                BatchAnnotateImagesResponse batchResponse =
                        null;
                try {
                    batchResponse = vision.images().annotate(batchRequest).execute();
                    List<FaceAnnotation> faces = batchResponse.getResponses()
                            .get(0).getFaceAnnotations();

                    // Count faces
                    int numberOfFaces = faces.size();
                    Log.i("log-", "number Of Faces" + numberOfFaces);

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            ImageView mImageView;
                            mImageView = findViewById(R.id.imageViewId);
                            InputStream is = getResources().openRawResource(R.raw.skate);
                            mImageView.setImageBitmap(BitmapFactory.decodeStream(is));
                        }
                    });


                    // Get joy likelihood for each face
                    String likelihoods = "";
                    for (int i = 0; i < numberOfFaces; i++) {
                        likelihoods += "\n It is " +
                                faces.get(i).getJoyLikelihood() +
                                " that face " + i + " is happy";
                    }

                    // Concatenate everything
                    final String message =
                            "This photo has " + numberOfFaces + " faces" + likelihoods;

                    // Display toast on UI thread
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),
                                    message, Toast.LENGTH_LONG).show();
                        }
                    });
               }
                catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
    }
    public void imageClick(View view){
        imgFavorite = findViewById(R.id.imageView1);
        open();
    }
    public void open(){
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //IMAGE CAPTURE CODE
        startActivityForResult(intent, 0);
    }
    protected void onActivityResult(int requestCode,int resultCode,Intent data){
        super.onActivityResult(requestCode,resultCode,data);
        Bitmap bitmap=(Bitmap)data.getExtras().get("data");
        imgFavorite.setImageBitmap(bitmap);
    }

Solution

  • You can trigger a Camera intent and tell it where to save your picture, after that you can open the file as an InputStream. To do so you need to pass the file Uri like this:

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    

    If you don't pass the File Uri you'll receive a thumbnail not the full size photo. For more details take a look a the docs:

    https://developer.android.com/training/camera/photobasics#TaskPath