• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
getImageView()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
runGraphOnImage(String filePath, String fileName)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
clearImagesSavedTextView()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
captureImages()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
onCreate(Bundle savedInstanceState)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
onPause()233     public void onPause() {
234         super.onPause();
235         Log.i(TAG, "onPause");
236         if (mContext != null) {
237             mContext.onPause();
238         }
239     }
240 
241     @Override
onResume()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
onStop()255     public void onStop() {
256         super.onStop();
257         Log.i(TAG, "onStop");
258     }
259 
260     // Build the Filtergraph for Camera
loadGraph()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
runGraph()284     private void runGraph() {
285         mRunner.setIsVerbose(true);
286         mRunner.start(mGraph);
287     }
288 }
289