1+ package com .kbyai .facelivedemo ;
2+
3+
4+ import android .Manifest ;
5+ import android .annotation .SuppressLint ;
6+ import android .content .pm .PackageManager ;
7+ import android .graphics .Bitmap ;
8+ import android .media .Image ;
9+ import android .os .Bundle ;
10+ import android .util .Log ;
11+ import android .util .Size ;
12+ import android .view .View ;
13+ import android .widget .ImageView ;
14+ import android .widget .TextView ;
15+
16+ import androidx .annotation .NonNull ;
17+ import androidx .appcompat .app .AppCompatActivity ;
18+ import androidx .camera .core .Camera ;
19+ import androidx .camera .core .CameraSelector ;
20+ import androidx .camera .core .ImageAnalysis ;
21+ import androidx .camera .core .ImageProxy ;
22+ import androidx .camera .core .Preview ;
23+ import androidx .camera .lifecycle .ProcessCameraProvider ;
24+ import androidx .camera .view .PreviewView ;
25+ import androidx .core .app .ActivityCompat ;
26+ import androidx .core .content .ContextCompat ;
27+
28+ import com .google .common .util .concurrent .ListenableFuture ;
29+ import com .kbyai .facesdk .FaceBox ;
30+ import com .kbyai .facesdk .FaceSDK ;
31+
32+ import java .nio .ByteBuffer ;
33+ import java .util .List ;
34+ import java .util .concurrent .ExecutionException ;
35+ import java .util .concurrent .ExecutorService ;
36+ import java .util .concurrent .Executors ;
37+
38+ import static androidx .camera .core .ImageAnalysis .STRATEGY_KEEP_ONLY_LATEST ;
39+
40+ public class CameraActivity extends AppCompatActivity {
41+
42+ static String TAG = CameraActivity .class .getSimpleName ();
43+ static int PREVIEW_WIDTH = 720 ;
44+ static int PREVIEW_HEIGHT = 1280 ;
45+ static float LIVENESS_THRESHOLD = 0.7f ;
46+
47+ private ExecutorService cameraExecutorService ;
48+ private PreviewView viewFinder ;
49+ private int lensFacing = CameraSelector .LENS_FACING_FRONT ;
50+
51+ private Preview preview = null ;
52+ private ImageAnalysis imageAnalyzer = null ;
53+ private Camera camera = null ;
54+ private CameraSelector cameraSelector = null ;
55+ private ProcessCameraProvider cameraProvider = null ;
56+
57+ private FaceView faceView ;
58+
59+ private TextView initView ;
60+
61+ @ Override
62+ protected void onCreate (Bundle savedInstanceState ) {
63+ super .onCreate (savedInstanceState );
64+ setContentView (R .layout .activity_camera );
65+
66+ viewFinder = findViewById (R .id .preview );
67+ faceView = findViewById (R .id .faceView );
68+ initView = findViewById (R .id .initView );
69+ cameraExecutorService = Executors .newFixedThreadPool (1 );
70+
71+ int ret = FaceSDK .setActivation ("GcVbBmdTI24WPXz3tBsr87dHU/KzmFuMYWm4SrLoFrFECoUouwdeSkWhAHi+k/AAYQW22jvctX+j\n " +
72+ "oDg+I1VLKJQgnJS2d80bwCKceYFXOc9A7jBi0/BEKx4PeSGz/PEpoPm/fFT9GrXXnLI4jZj8tMRX\n " +
73+ "cYS4MO7ECQkQmFtqU4wx63mV2MP97WCurOGBRUuVm4dK+mObTVA/rBNrgS75ArcjwwIKexMU5YCY\n " +
74+ "qjLsmADlcnEu5vuYCagDeHyCkUIqvl0/KLicM68BEG2ItUDflhOZJkjOof3gWPSmzJveXuoyPCR5\n " +
75+ "aSBeesUcwQv9xdKciBacMX/pDDMsbqv614gQ5A==" );
76+
77+ if (ret == FaceSDK .SDK_SUCCESS ) {
78+ ret = FaceSDK .init (getAssets ());
79+ }
80+
81+ if (ret != FaceSDK .SDK_SUCCESS ) {
82+ initView .setVisibility (View .VISIBLE );
83+ if (ret == FaceSDK .SDK_LICENSE_KEY_ERROR ) {
84+ initView .setText ("Invalid license!" );
85+ } else if (ret == FaceSDK .SDK_LICENSE_APPID_ERROR ) {
86+ initView .setText ("Invalid error!" );
87+ } else if (ret == FaceSDK .SDK_LICENSE_EXPIRED ) {
88+ initView .setText ("License expired!" );
89+ } else if (ret == FaceSDK .SDK_NO_ACTIVATED ) {
90+ initView .setText ("No activated!" );
91+ } else if (ret == FaceSDK .SDK_INIT_ERROR ) {
92+ initView .setText ("Init error!" );
93+ }
94+ }
95+
96+ if (ContextCompat .checkSelfPermission (this , Manifest .permission .CAMERA )
97+ == PackageManager .PERMISSION_DENIED ) {
98+
99+ ActivityCompat .requestPermissions (this , new String []{Manifest .permission .CAMERA }, 1 );
100+ } else {
101+ viewFinder .post (() ->
102+ {
103+ setUpCamera ();
104+ });
105+ }
106+ }
107+
108+ @ Override
109+ public void onRequestPermissionsResult (int requestCode , @ NonNull String [] permissions , @ NonNull int [] grantResults ) {
110+ super .onRequestPermissionsResult (requestCode , permissions , grantResults );
111+
112+ if (requestCode == 1 ) {
113+ if (ContextCompat .checkSelfPermission (this , Manifest .permission .CAMERA )
114+ == PackageManager .PERMISSION_GRANTED ) {
115+
116+ viewFinder .post (() ->
117+ {
118+ setUpCamera ();
119+ });
120+ }
121+ }
122+ }
123+
124+ private void setUpCamera ()
125+ {
126+ ListenableFuture <ProcessCameraProvider > cameraProviderFuture = ProcessCameraProvider .getInstance (CameraActivity .this );
127+ cameraProviderFuture .addListener (() -> {
128+
129+ // CameraProvider
130+ try {
131+ cameraProvider = cameraProviderFuture .get ();
132+ } catch (ExecutionException e ) {
133+ } catch (InterruptedException e ) {
134+ }
135+
136+ // Build and bind the camera use cases
137+ bindCameraUseCases ();
138+
139+ }, ContextCompat .getMainExecutor (CameraActivity .this ));
140+ }
141+
142+ @ SuppressLint ({"RestrictedApi" , "UnsafeExperimentalUsageError" })
143+ private void bindCameraUseCases ()
144+ {
145+ int rotation = viewFinder .getDisplay ().getRotation ();
146+
147+ cameraSelector = new CameraSelector .Builder ().requireLensFacing (lensFacing ).build ();
148+
149+ preview = new Preview .Builder ()
150+ .setTargetResolution (new Size (PREVIEW_WIDTH , PREVIEW_HEIGHT ))
151+ .setTargetRotation (rotation )
152+ .build ();
153+
154+ imageAnalyzer = new ImageAnalysis .Builder ()
155+ .setBackpressureStrategy (STRATEGY_KEEP_ONLY_LATEST )
156+ .setTargetResolution (new Size (PREVIEW_WIDTH , PREVIEW_HEIGHT ))
157+ // Set initial target rotation, we will have to call this again if rotation changes
158+ // during the lifecycle of this use case
159+ .setTargetRotation (rotation )
160+ .build ();
161+
162+ imageAnalyzer .setAnalyzer (cameraExecutorService , new FaceAnalyzer ());
163+
164+ cameraProvider .unbindAll ();
165+
166+ try {
167+ camera = cameraProvider .bindToLifecycle (
168+ this , cameraSelector , preview , imageAnalyzer );
169+
170+ preview .setSurfaceProvider (viewFinder .getSurfaceProvider ());
171+ } catch (Exception exc ) {
172+ }
173+ }
174+
175+ class FaceAnalyzer implements ImageAnalysis .Analyzer
176+ {
177+ @ SuppressLint ("UnsafeExperimentalUsageError" )
178+ @ Override
179+ public void analyze (@ NonNull ImageProxy imageProxy )
180+ {
181+ analyzeImage (imageProxy );
182+ }
183+ }
184+
185+ @ SuppressLint ("UnsafeExperimentalUsageError" )
186+ private void analyzeImage (ImageProxy imageProxy )
187+ {
188+ try
189+ {
190+ Image image = imageProxy .getImage ();
191+
192+ Image .Plane [] planes = image .getPlanes ();
193+ ByteBuffer yBuffer = planes [0 ].getBuffer ();
194+ ByteBuffer uBuffer = planes [1 ].getBuffer ();
195+ ByteBuffer vBuffer = planes [2 ].getBuffer ();
196+
197+ int ySize = yBuffer .remaining ();
198+ int uSize = uBuffer .remaining ();
199+ int vSize = vBuffer .remaining ();
200+
201+ byte [] nv21 = new byte [ySize + uSize + vSize ];
202+ yBuffer .get (nv21 , 0 , ySize );
203+ vBuffer .get (nv21 , ySize , vSize );
204+ uBuffer .get (nv21 , ySize + vSize , uSize );
205+
206+ Bitmap bitmap = FaceSDK .yuv2Bitmap (nv21 , image .getWidth (), image .getHeight (), 7 );
207+ List <FaceBox > faceBoxes = FaceSDK .faceDetection (bitmap );
208+
209+ runOnUiThread (new Runnable () {
210+ @ Override
211+ public void run () {
212+ faceView .setFrameSize (new Size (bitmap .getWidth (), bitmap .getHeight ()));
213+ faceView .setFaceBoxes (faceBoxes );
214+ }
215+ });
216+ }
217+ catch (Exception e )
218+ {
219+ e .printStackTrace ();
220+ }
221+ finally
222+ {
223+ imageProxy .close ();
224+ }
225+ }
226+ }
0 commit comments