Home | History | Annotate | Download | only in simplecamera
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package androidx.media.filterfw.samples.simplecamera;
     18 
     19 import android.app.Activity;
     20 import android.content.Intent;
     21 import android.graphics.Bitmap;
     22 import android.graphics.drawable.BitmapDrawable;
     23 import android.graphics.drawable.Drawable;
     24 import android.os.Bundle;
     25 import android.os.Handler;
     26 import android.provider.MediaStore;
     27 import android.util.Log;
     28 import android.view.LayoutInflater;
     29 import android.view.SurfaceView;
     30 import android.view.View;
     31 import android.view.View.OnClickListener;
     32 import android.widget.AdapterView;
     33 import android.widget.Button;
     34 import android.widget.ImageView;
     35 import android.widget.LinearLayout;
     36 import android.widget.Spinner;
     37 import android.widget.TextView;
     38 import androidx.media.filterfw.FilterGraph;
     39 import androidx.media.filterfw.GraphReader;
     40 import androidx.media.filterfw.GraphRunner;
     41 import androidx.media.filterfw.MffContext;
     42 
     43 import java.io.IOException;
     44 import java.text.SimpleDateFormat;
     45 import java.util.ArrayList;
     46 import java.util.Calendar;
     47 
     48 
     49 public class SmartCamera extends Activity {
     50 
     51     private SurfaceView mCameraView;
     52     private TextView mGoodBadTextView;
     53     private TextView mFPSTextView;
     54     private TextView mEyesTextView;
     55     private TextView mSmilesTextView;
     56     private TextView mScoreTextView;
     57     private static ImageView mImageView1;
     58     private static ImageView mImageView2;
     59     private static ImageView mImageView3;
     60     private static ImageView mImageView4;
     61     private static ImageView mImageView5;
     62     private Button mStartStopButton;
     63     private TextView mImagesSavedTextView;
     64     private Spinner mSpinner;
     65     private LinearLayout mLinearLayout;
     66 
     67     private MffContext mContext;
     68     private FilterGraph mGraph;
     69     private GraphRunner mRunner;
     70     private Handler mHandler = new Handler();
     71 
     72     private static final String TAG = "SmartCamera";
     73     private static final boolean sUseFacialExpression = false;
     74     private boolean isPendingRunGraph = false;
     75 
     76     private static ArrayList<ImageView> mImages;
     77     private static int count = -1;
     78     private static boolean countHasReachedMax = false;
     79     private static int numImages = 0;
     80 
     81     // Function to return the correct image view to display the current bitmap
     82     public static ImageView getImageView() {
     83         if (count == numImages-1) countHasReachedMax = true;
     84         count = (count+1) % numImages;
     85         return mImages.get(count);
     86     }
     87 
     88     // Function used to run images through the graph, mainly for CSV data generation
     89     public void runGraphOnImage(String filePath, String fileName) {
     90         if(fileName.endsWith(".jpg") == false) {
     91             return;
     92         }
     93         mGraph.getVariable("gallerySource").setValue(filePath + "/" + fileName);
     94         Log.v(TAG, "runGraphOnImage : : " + filePath + " name: " + fileName);
     95         mGraph.getVariable("imageName").setValue(fileName);
     96         mGraph.getVariable("filePath").setValue(filePath); // wrong
     97         try {
     98             Thread.sleep(400);
     99         } catch (InterruptedException e) {
    100             // TODO Auto-generated catch block
    101             e.printStackTrace();
    102         }
    103     }
    104 
    105     // Function to clear the "Images Saved" text off the screen
    106     private void clearImagesSavedTextView() {
    107         mImagesSavedTextView.setText("");
    108     }
    109 
    110     // Function to capture the images in the current imageviews and save them to the gallery
    111     private void captureImages() {
    112         ((WaveTriggerFilter) mGraph.getFilter("snapEffect")).trigger();
    113         mGraph.getVariable("startCapture").setValue(false);
    114         Bitmap bitmap = null;
    115         Drawable res = getResources().getDrawable(R.drawable.black_screen);
    116         Calendar cal = Calendar.getInstance();
    117         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");
    118 
    119         Log.v(TAG, "numImages: " + numImages + " count: " + count +
    120                 " hasReachedMax: " + countHasReachedMax);
    121         int maxI = countHasReachedMax ? numImages : count+1;
    122         if(maxI != 0) {
    123             if (maxI == 1) mImagesSavedTextView.setText("Image Saved");
    124             else {
    125                 mImagesSavedTextView.setText("" + maxI + " Images Saved");
    126             }
    127         }
    128         for (int i = 0; i < maxI; i++) {
    129             bitmap = ((BitmapDrawable)mImages.get(i).getDrawable()).getBitmap();
    130             mImages.get(i).setImageDrawable(res);
    131             MediaStore.Images.Media.insertImage(getContentResolver(), bitmap,
    132                     sdf.format(cal.getTime()) + "_image" + i + ".jpg", "image " + i);
    133         }
    134         mStartStopButton.setText("Start");
    135         count = -1;
    136         countHasReachedMax = false;
    137         mSpinner.setEnabled(true);
    138         mHandler.postDelayed(new Runnable() {
    139             public void run() {
    140                 clearImagesSavedTextView();
    141             }
    142         }, 5000);
    143     }
    144 
    145     @Override
    146     public void onCreate(Bundle savedInstanceState) {
    147         super.onCreate(savedInstanceState);
    148         setContentView(R.layout.simplecamera);
    149         setTitle("Smart Camera");
    150 
    151         mContext = new MffContext(this);
    152 
    153         mCameraView = (SurfaceView) findViewById(R.id.cameraView);
    154         mGoodBadTextView = (TextView) findViewById(R.id.goodOrBadTextView);
    155         mFPSTextView = (TextView) findViewById(R.id.fpsTextView);
    156         mScoreTextView = (TextView) findViewById(R.id.scoreTextView);
    157         mStartStopButton = (Button) findViewById(R.id.startButton);
    158         mImagesSavedTextView = (TextView) findViewById(R.id.imagesSavedTextView);
    159         mImagesSavedTextView.setText("");
    160         mSpinner = (Spinner) findViewById(R.id.spinner);
    161         mLinearLayout = (LinearLayout) findViewById(R.id.scrollViewLinearLayout);
    162         mImages = new ArrayList<ImageView>();
    163 
    164         // Spinner is used to determine how many image views are displayed at the bottom
    165         // of the screen. Based on the item position that is selected, we inflate that
    166         // many imageviews into the bottom linear layout.
    167         mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    168             @Override
    169             public void onItemSelected(AdapterView<?> parentView, View selectedItemView,
    170                     int position, long id) {
    171                 mLinearLayout.removeViews(0,numImages);
    172                 numImages = position+1;
    173                 mImages.clear();
    174                 LayoutInflater inflater = getLayoutInflater();
    175                 for (int i = 0; i < numImages; i++) {
    176                     ImageView tmp = (ImageView) inflater.inflate(R.layout.imageview, null);
    177                     mImages.add(tmp);
    178                     mLinearLayout.addView(tmp);
    179                 }
    180             }
    181 
    182             @Override
    183             public void onNothingSelected(AdapterView<?> parentView) {
    184             }
    185         });
    186 
    187         numImages = mSpinner.getSelectedItemPosition()+1;
    188         mImages.clear();
    189         LayoutInflater inflater = getLayoutInflater();
    190         for (int i = 0; i < numImages; i++) {
    191             ImageView tmp = (ImageView) inflater.inflate(R.layout.imageview, null);
    192             mImages.add(tmp);
    193             mLinearLayout.addView(tmp);
    194 
    195         }
    196 
    197         // Button used to start and stop the capture of images when they are deemed great
    198         mStartStopButton.setOnClickListener(new OnClickListener() {
    199             @Override
    200             public void onClick(View v) {
    201                 if (mStartStopButton.getText().equals("Start")) {
    202                     mGraph.getVariable("startCapture").setValue(true);
    203                     mStartStopButton.setText("Stop");
    204                     mSpinner.setEnabled(false);
    205                 } else {
    206                     boolean tmp = (Boolean) mGraph.getVariable("startCapture").getValue();
    207                     if (tmp == false) {
    208                         return;
    209                     }
    210                     if (count == numImages-1) countHasReachedMax = true;
    211                     captureImages();
    212                 }
    213             }
    214         });
    215 
    216         // Button to open the gallery to show the images in there
    217         Button galleryOpen = (Button) findViewById(R.id.galleryOpenButton);
    218         galleryOpen.setOnClickListener(new OnClickListener() {
    219            @Override
    220            public void onClick(View v) {
    221                Intent openGalleryIntent = new Intent(Intent.ACTION_MAIN);
    222                openGalleryIntent.addCategory(Intent.CATEGORY_APP_GALLERY);
    223                startActivity(openGalleryIntent);
    224            }
    225         });
    226 
    227         loadGraph();
    228         mGraph.getVariable("startCapture").setValue(false);
    229         runGraph();
    230     }
    231 
    232     @Override
    233     public void onPause() {
    234         super.onPause();
    235         Log.i(TAG, "onPause");
    236         if (mContext != null) {
    237             mContext.onPause();
    238         }
    239     }
    240 
    241     @Override
    242     public void onResume() {
    243         super.onResume();
    244         Log.i(TAG, "onResume");
    245         if (mContext != null) {
    246             mContext.onResume();
    247         }
    248         if (isPendingRunGraph) {
    249             isPendingRunGraph = false;
    250             runGraph();
    251         }
    252     }
    253 
    254     @Override
    255     public void onStop() {
    256         super.onStop();
    257         Log.i(TAG, "onStop");
    258     }
    259 
    260     // Build the Filtergraph for Camera
    261     private void loadGraph() {
    262         try {
    263             mGraph = GraphReader.readXmlGraphResource(mContext, R.raw.camera_graph);
    264             mRunner = mGraph.getRunner();
    265 
    266             // Connect views
    267             mGraph.bindFilterToView("camViewTarget", mCameraView);
    268             mGraph.bindFilterToView("goodOrBadTextView", mGoodBadTextView);
    269             mGraph.bindFilterToView("fpsTextView", mFPSTextView);
    270             mGraph.bindFilterToView("scoreTextView", mScoreTextView);
    271 
    272             // Used for Facial Expressions
    273             if (sUseFacialExpression) {
    274                 mGraph.bindFilterToView("eyesTextView", mEyesTextView);
    275                 mGraph.bindFilterToView("smilesTextView", mSmilesTextView);
    276             }
    277 
    278         } catch (IOException e) {
    279             e.printStackTrace();
    280         }
    281     }
    282 
    283     // Asynchronously run the filtergraph
    284     private void runGraph() {
    285         mRunner.setIsVerbose(true);
    286         mRunner.start(mGraph);
    287     }
    288 }
    289