package cn.com.basic.face.base;
|
|
import android.Manifest;
|
import android.app.AlertDialog;
|
import android.content.Context;
|
import android.content.DialogInterface;
|
import android.content.pm.ActivityInfo;
|
import android.content.pm.PackageManager;
|
import android.content.res.Configuration;
|
import android.graphics.Bitmap;
|
import android.graphics.BitmapFactory;
|
import android.graphics.Canvas;
|
import android.graphics.Color;
|
import android.graphics.Paint;
|
import android.hardware.Camera;
|
import android.os.Handler;
|
import android.support.design.widget.TabLayout;
|
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.Fragment;
|
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentPagerAdapter;
|
import android.support.v4.content.ContextCompat;
|
import android.support.v4.view.ViewPager;
|
import android.os.Bundle;
|
import android.view.LayoutInflater;
|
import android.view.MotionEvent;
|
import android.view.SurfaceHolder;
|
import android.view.SurfaceView;
|
import android.view.View;
|
import android.view.ViewGroup;
|
import android.view.WindowManager;
|
import android.widget.EditText;
|
import android.widget.ImageView;
|
import android.widget.LinearLayout;
|
import android.widget.TextView;
|
import android.widget.Toast;
|
|
import com.bsk.zhangbo.demoforbsk.R;
|
import com.luxand.FSDK;
|
|
import cn.com.basic.face.discern.common.CommonVariables;
|
import cn.com.basic.face.discern.query.item.SurveillanceQueryItem;
|
import cn.com.basic.face.fragment.AttenderRegisterFragment;
|
import cn.com.basic.face.fragment.SurveillanceFragment;
|
import cn.com.basic.face.service.SurveillanceMng;
|
import cn.com.basic.face.util.FileUtil;
|
import cn.com.basic.face.util.NativeImg;
|
import cn.com.basic.face.util.TabNameUtil;
|
import cn.com.basic.face.fragment.AttendanceFragment;
|
import cn.com.basic.face.fragment.CheckInFragment;
|
import cn.com.basic.face.fragment.DeviceFragment;
|
import cn.com.basic.face.fragment.PhoneCallFragment;
|
import cn.com.basic.face.fragment.VisitorRegisterFragment;
|
import cn.com.basic.face.fragment.VisitFragment;
|
|
import java.io.File;
|
import java.io.FileOutputStream;
|
import java.io.InputStream;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.ReentrantLock;
|
|
public class MainActivity extends BaseActivity implements View.OnClickListener{
|
|
private static MainActivity instance;
|
|
private static TabLayout mTabLayout;
|
private static ViewPager mViewPager;
|
|
public static void selectPage(int pageNum) {
|
mTabLayout.getTabAt(pageNum).select();
|
}
|
|
@Override
|
public int getLayoutId() {
|
return R.layout.activity_main;
|
}
|
|
@Override
|
public void initViews(Bundle savedInstanceState) {
|
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
|
mViewPager = (ViewPager) findViewById(R.id.viewpager);
|
mTabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
|
instance = this;
|
}
|
|
@Override
|
public void initData() {
|
List<String> tabNamesList = Arrays.asList(TabNameUtil.tabNames);
|
int[] tabIcons = TabNameUtil.tabIcons;
|
MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),MainActivity.this);
|
myFragmentPagerAdapter.addFragment(SurveillanceFragment.getInstance(), tabNamesList.get(0),tabIcons[0]);
|
// myFragmentPagerAdapter.addFragment(VisitorRegisterFragment.getInstance(), tabNamesList.get(1),tabIcons[1]);
|
myFragmentPagerAdapter.addFragment(AttenderRegisterFragment.getInstance(), tabNamesList.get(1),tabIcons[1]);
|
myFragmentPagerAdapter.addFragment(CheckInFragment.getInstance(), tabNamesList.get(2),tabIcons[2]);
|
myFragmentPagerAdapter.addFragment(PhoneCallFragment.getInstance(), tabNamesList.get(3),tabIcons[3]);
|
myFragmentPagerAdapter.addFragment(VisitFragment.getInstance(), tabNamesList.get(4),tabIcons[4]);
|
myFragmentPagerAdapter.addFragment(AttendanceFragment.getInstance(), tabNamesList.get(5),tabIcons[5]);
|
myFragmentPagerAdapter.addFragment(DeviceFragment.getInstance(), tabNamesList.get(6),tabIcons[6]);
|
mViewPager.setAdapter(myFragmentPagerAdapter);
|
mViewPager.setOffscreenPageLimit(6);//viewpager缓存个数
|
mTabLayout.setupWithViewPager(mViewPager);
|
mTabLayout.setTabMode(TabLayout.MODE_FIXED);
|
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
|
TabLayout.Tab tab = mTabLayout.getTabAt(i);
|
LinearLayout view = (LinearLayout)myFragmentPagerAdapter.getTabView(i);
|
tab.setCustomView(view);
|
if (i == 0) {
|
tab.getCustomView().setSelected(true);
|
}
|
}
|
if (CommonVariables.ID_CARD) {
|
myThread = new MyThread();
|
myThread.start();
|
}
|
}
|
|
public static MainActivity getInstance() {
|
return instance;
|
}
|
|
public static class MyFragmentPagerAdapter extends FragmentPagerAdapter {
|
|
private final List<Fragment> mFragments = new ArrayList<>();
|
private final List<String> mFragmentTitles = new ArrayList<>();
|
private final List<Integer> mFragmentIcons = new ArrayList<>();
|
private Context context;
|
public MyFragmentPagerAdapter(FragmentManager fm, Context context) {
|
super(fm);
|
this.context = context;
|
}
|
|
public void addFragment(Fragment fragment, String title,int drawable) {
|
mFragments.add(fragment);
|
mFragmentTitles.add(title);
|
mFragmentIcons.add(drawable);
|
}
|
|
@Override
|
public Fragment getItem(int position) {
|
return mFragments.get(position);
|
}
|
|
@Override
|
public int getCount() {
|
return mFragments.size();
|
}
|
|
@Override
|
public CharSequence getPageTitle(int position) {
|
return null;
|
}
|
|
public View getTabView(int position){
|
View view = LayoutInflater.from(context).inflate(R.layout.activity_main_tab,null);
|
TextView mTvTitle = (TextView) view.findViewById(R.id.tab_item_title);
|
mTvTitle.setText(mFragmentTitles.get(position));
|
ImageView mImgIcon = (ImageView) view.findViewById(R.id.tab_item_icon);
|
mImgIcon.setImageResource(mFragmentIcons.get(position));
|
return view;
|
}
|
|
}
|
|
boolean doubleBackToExitPressedOnce = false;
|
|
@Override
|
public void onBackPressed() {
|
if (doubleBackToExitPressedOnce) {
|
super.onBackPressed();
|
return;
|
}
|
|
this.doubleBackToExitPressedOnce = true;
|
Toast.makeText(this, "请再次按返回键退出", Toast.LENGTH_SHORT).show();
|
|
new Handler().postDelayed(new Runnable() {
|
|
@Override
|
public void run() {
|
doubleBackToExitPressedOnce=false;
|
}
|
}, 2000);
|
}
|
|
|
private MyThread myThread;
|
class MyThread extends Thread{
|
@Override
|
public void run() {
|
try {
|
setBmpDecodeEnv();
|
Thread.sleep(2000);
|
} catch (InterruptedException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
/**
|
* 将raw下的文件复制到sdCard
|
*/
|
public boolean setBmpDecodeEnv() {
|
|
String path=getFilesDir().getAbsolutePath();
|
String filename = "base.dat";
|
try{
|
String databaseFilename = path + "/" + filename;
|
File dir = new File(path);
|
if (!dir.exists())
|
dir.mkdir();
|
if (!(new File(databaseFilename)).exists()){
|
InputStream is = getResources().openRawResource(R.raw.base);
|
FileOutputStream fos = new FileOutputStream(databaseFilename);
|
byte[] buffer = new byte[8192];
|
int count = 0;
|
while ((count = is.read(buffer)) > 0)
|
{
|
fos.write(buffer, 0, count);
|
}
|
fos.close();
|
is.close();
|
}
|
}
|
catch (Exception e){
|
System.out.println(e.getMessage());
|
return false;
|
}
|
|
String filename1 = "license.lic";
|
try{
|
String databaseFilename = path + "/" + filename1;
|
File dir = new File(path);
|
if (!dir.exists())
|
dir.mkdir();
|
if (!(new File(databaseFilename)).exists()){
|
InputStream is = getResources().openRawResource(R.raw.license);
|
FileOutputStream fos = new FileOutputStream(databaseFilename);
|
byte[] buffer = new byte[8192];
|
int count = 0;
|
while ((count = is.read(buffer)) > 0)
|
{
|
fos.write(buffer, 0, count);
|
}
|
fos.close();
|
is.close();
|
}
|
}
|
catch (Exception e){
|
System.out.println(e.getMessage());
|
return false;
|
}
|
return true;
|
}
|
|
|
////////////////////////////////////////////////////////
|
private boolean mIsFailed = false;
|
public Preview mPreview;
|
public ProcessImageAndDrawResults mDraw;
|
private final String database = "Memory50.dat";
|
private final String help_text = "help";
|
|
public static float sDensity = 1.0f;
|
|
@Override
|
public void onCreate(Bundle savedInstanceState) {
|
super.onCreate(savedInstanceState);
|
if (CommonVariables.FACE_SERVER) {
|
sDensity = getResources().getDisplayMetrics().scaledDensity;
|
|
int res = 0;
|
if (res != FSDK.FSDKE_OK) {
|
mIsFailed = true;
|
showErrorAndClose("failed", res);
|
} else {
|
FSDK.Initialize();
|
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
mDraw = new ProcessImageAndDrawResults(this);
|
mPreview = new Preview(this, mDraw);
|
mDraw.mTracker = new FSDK.HTracker();
|
String templatePath = this.getApplicationInfo().dataDir + "/" + database;
|
if (FSDK.FSDKE_OK != FSDK.LoadTrackerMemoryFromFile(mDraw.mTracker, templatePath)) {
|
res = FSDK.CreateTracker(mDraw.mTracker);
|
if (FSDK.FSDKE_OK != res) {
|
showErrorAndClose("Error creating tracker", res);
|
}
|
}
|
resetTrackerParameters();
|
|
//setContentView(mPreview); //creates MainActivity contents
|
//addContentView(mDraw, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
|
|
// Menu
|
// LayoutInflater inflater = (LayoutInflater)this.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
|
// View buttons = inflater.inflate(R.layout.bottom_menu, null );
|
// buttons.findViewById(R.id.helpButton).setOnClickListener(this);
|
// buttons.findViewById(R.id.clearButton).setOnClickListener(this);
|
// addContentView(buttons, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
}
|
}
|
}
|
|
@Override
|
public void onClick(View view) {
|
if(CommonVariables.FACE_SERVER) {
|
if (view.getId() == R.id.helpButton) {
|
showMessage(help_text);
|
} else if (view.getId() == R.id.clearButton) {
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
builder.setMessage("Are you sure to clear the memory?" )
|
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
@Override public void onClick(DialogInterface dialogInterface, int j) {
|
pauseProcessingFrames();
|
FSDK.ClearTracker(mDraw.mTracker);
|
resetTrackerParameters();
|
resumeProcessingFrames();
|
}
|
})
|
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
@Override public void onClick(DialogInterface dialogInterface, int j) {
|
}
|
})
|
.setCancelable(false)
|
.show();
|
}
|
}
|
}
|
|
@Override
|
protected void onPause() {
|
super.onPause();
|
if(CommonVariables.FACE_SERVER) {
|
pauseProcessingFrames();
|
String templatePath = this.getApplicationInfo().dataDir + "/" + database;
|
FSDK.SaveTrackerMemoryToFile(mDraw.mTracker, templatePath);
|
}
|
}
|
|
@Override
|
protected void onResume() {
|
super.onResume();
|
if(CommonVariables.FACE_SERVER) {
|
if (mIsFailed)
|
return;
|
resumeProcessingFrames();
|
}
|
}
|
|
public void showErrorAndClose(String error, int code) {
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
builder.setMessage(error + ": " + code)
|
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
@Override
|
public void onClick(DialogInterface dialogInterface, int i) {
|
android.os.Process.killProcess(android.os.Process.myPid());
|
}
|
})
|
.show();
|
}
|
|
public void showMessage(String message) {
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
builder.setMessage(message)
|
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
@Override
|
public void onClick(DialogInterface dialogInterface, int i) {
|
}
|
})
|
.setCancelable(false)
|
.show();
|
}
|
|
private void resetTrackerParameters() {
|
int errpos[] = new int[1];
|
FSDK.SetTrackerMultipleParameters(mDraw.mTracker, "ContinuousVideoFeed=true;FacialFeatureJitterSuppression=0;RecognitionPrecision=0;Threshold=0.996;Threshold2=0.9995;ThresholdFeed=0.97;MemoryLimit=1000;HandleArbitraryRotations=false;DetermineFaceRotationAngle=false;InternalResizeWidth=70;FaceDetectionThreshold=5;", errpos);
|
if (errpos[0] != 0) {
|
showErrorAndClose("Error setting tracker parameters, position", errpos[0]);
|
}
|
}
|
|
private void pauseProcessingFrames() {
|
mDraw.mStopping = 1;
|
|
for (int i=0; i<100; ++i) {
|
if (mDraw.mStopped != 0) break;
|
try { Thread.sleep(10); }
|
catch (Exception ex) {}
|
}
|
}
|
|
private void resumeProcessingFrames() {
|
mDraw.mStopped = 0;
|
mDraw.mStopping = 0;
|
}
|
}
|
|
|
|
class FaceRectangle {
|
public int x1, y1, x2, y2;
|
}
|
|
class ProcessImageAndDrawResults extends View {
|
public FSDK.HTracker mTracker;
|
|
final int MAX_FACES = 5;
|
final FaceRectangle[] mFacePositions = new FaceRectangle[MAX_FACES];
|
final long[] mIDs = new long[MAX_FACES];
|
final Lock faceLock = new ReentrantLock();
|
int mTouchedIndex;
|
long mTouchedID;
|
int mStopping;
|
int mStopped;
|
|
Context mContext;
|
Paint mPaintGreen, mPaintBlue, mPaintBlueTransparent;
|
byte[] mYUVData;
|
byte[] mRGBData;
|
int mImageWidth, mImageHeight;
|
boolean first_frame_saved;
|
boolean rotated;
|
|
int GetFaceFrame(FSDK.FSDK_Features Features, FaceRectangle fr)
|
{
|
if (Features == null || fr == null)
|
return FSDK.FSDKE_INVALID_ARGUMENT;
|
|
float u1 = Features.features[0].x;
|
float v1 = Features.features[0].y;
|
float u2 = Features.features[1].x;
|
float v2 = Features.features[1].y;
|
float xc = (u1 + u2) / 2;
|
float yc = (v1 + v2) / 2;
|
int w = (int)Math.pow((u2 - u1) * (u2 - u1) + (v2 - v1) * (v2 - v1), 0.5);
|
|
fr.x1 = (int)(xc - w * 1.6 * 0.9);
|
fr.y1 = (int)(yc - w * 1.1 * 0.9);
|
fr.x2 = (int)(xc + w * 1.6 * 0.9);
|
fr.y2 = (int)(yc + w * 2.1 * 0.9);
|
if (fr.x2 - fr.x1 > fr.y2 - fr.y1) {
|
fr.x2 = fr.x1 + fr.y2 - fr.y1;
|
} else {
|
fr.y2 = fr.y1 + fr.x2 - fr.x1;
|
}
|
return 0;
|
}
|
|
|
public ProcessImageAndDrawResults(Context context) {
|
super(context);
|
|
mTouchedIndex = -1;
|
|
mStopping = 0;
|
mStopped = 0;
|
rotated = false;
|
mContext = context;
|
mPaintGreen = new Paint();
|
mPaintGreen.setStyle(Paint.Style.FILL);
|
mPaintGreen.setColor(Color.GREEN);
|
mPaintGreen.setTextSize(18 * MainActivity.sDensity);
|
mPaintGreen.setTextAlign(Paint.Align.CENTER);
|
mPaintBlue = new Paint();
|
mPaintBlue.setStyle(Paint.Style.FILL);
|
mPaintBlue.setColor(Color.BLUE);
|
mPaintBlue.setTextSize(18 * MainActivity.sDensity);
|
mPaintBlue.setTextAlign(Paint.Align.CENTER);
|
|
mPaintBlueTransparent = new Paint();
|
mPaintBlueTransparent.setStyle(Paint.Style.STROKE);
|
mPaintBlueTransparent.setStrokeWidth(2);
|
mPaintBlueTransparent.setColor(Color.BLUE);
|
mPaintBlueTransparent.setTextSize(25);
|
|
mYUVData = null;
|
mRGBData = null;
|
|
first_frame_saved = false;
|
}
|
|
@Override
|
protected void onDraw(Canvas canvas) {
|
if (mStopping == 1) {
|
mStopped = 1;
|
super.onDraw(canvas);
|
return;
|
}
|
|
if (mYUVData == null || mTouchedIndex != -1) {
|
super.onDraw(canvas);
|
return;
|
}
|
|
int canvasWidth = canvas.getWidth();
|
|
decodeYUV420SP(mRGBData, mYUVData, mImageWidth, mImageHeight);
|
|
FSDK.HImage Image = new FSDK.HImage();
|
FSDK.FSDK_IMAGEMODE imagemode = new FSDK.FSDK_IMAGEMODE();
|
imagemode.mode = FSDK.FSDK_IMAGEMODE.FSDK_IMAGE_COLOR_24BIT;
|
FSDK.LoadImageFromBuffer(Image, mRGBData, mImageWidth, mImageHeight, mImageWidth*3, imagemode);
|
FSDK.MirrorImage(Image, false);
|
FSDK.HImage RotatedImage = new FSDK.HImage();
|
FSDK.CreateEmptyImage(RotatedImage);
|
|
int ImageWidth = mImageWidth;
|
if (rotated) {
|
ImageWidth = mImageHeight;
|
FSDK.RotateImage90(Image, -1, RotatedImage);
|
} else {
|
FSDK.CopyImage(Image, RotatedImage);
|
}
|
|
// FSDK.TFacePosition fp11 = new FSDK.TFacePosition();
|
// FSDK.DetectFace(RotatedImage, fp11);
|
|
String surveillancePhotoName11 = "/storage/sdcard1/"+System.currentTimeMillis()+".jpg";
|
FSDK.SaveImageToFile(Image, surveillancePhotoName11);
|
|
|
FSDK.FreeImage(Image);
|
|
long IDs[] = new long[MAX_FACES];
|
long face_count[] = new long[1];
|
|
|
|
FSDK.FeedFrame(mTracker, 0, RotatedImage, face_count, IDs);
|
|
System.out.println("face_count="+face_count[0]);
|
|
faceLock.lock();
|
|
for (int i=0; i<MAX_FACES; ++i) {
|
mFacePositions[i] = new FaceRectangle();
|
mFacePositions[i].x1 = 0;
|
mFacePositions[i].y1 = 0;
|
mFacePositions[i].x2 = 0;
|
mFacePositions[i].y2 = 0;
|
mIDs[i] = IDs[i];
|
}
|
|
float ratio = (canvasWidth * 1.0f) / ImageWidth;
|
|
for (int i = 0; i < (int)face_count[0]; ++i) {
|
FSDK.FSDK_Features Eyes = new FSDK.FSDK_Features();
|
FSDK.GetTrackerEyes(mTracker, 0, mIDs[i], Eyes);
|
|
GetFaceFrame(Eyes, mFacePositions[i]);
|
mFacePositions[i].x1 *= ratio;
|
mFacePositions[i].y1 *= ratio;
|
mFacePositions[i].x2 *= ratio;
|
mFacePositions[i].y2 *= ratio;
|
}
|
if ((int)face_count[0] > 0) {
|
|
FSDK.HImage img2 = new FSDK.HImage();
|
FSDK.CreateEmptyImage(img2);
|
FSDK.TFacePosition fp = new FSDK.TFacePosition();
|
FSDK.DetectFace(RotatedImage, fp);
|
|
int x1 = (int)(fp.xc - 1.2*fp.w/2);
|
int y1 = (int)(fp.yc - 1.4*fp.w/2);
|
int x2 = (int)(fp.xc + 1.2*fp.w/2);
|
int y2 = (int)(fp.yc + 1.4*fp.w/2);
|
|
FSDK.CopyRect(RotatedImage, x1, y1, x2, y2, img2);
|
|
int maxWidth = 337;
|
int maxHeight = 450;
|
|
FSDK.ResizeImage(img2, Math.max((maxWidth+0.4)/(x2-x1+1), (maxHeight+0.4)/(y2-y1+1)), RotatedImage);
|
|
System.out.println("face_count="+face_count[0]);
|
String surveillancePhotoName = MainActivity.getInstance().getFilesDir().getAbsolutePath()+System.currentTimeMillis()+".jpg";
|
FSDK.SaveImageToFile(img2, surveillancePhotoName);
|
|
List bitmapList = new ArrayList();
|
for (int i = 0; i < 1; i++) {
|
NativeImg nativeImg = new NativeImg();
|
nativeImg.image = FileUtil.readFile(new File(surveillancePhotoName));
|
nativeImg.size = nativeImg.image.length;
|
SurveillanceQueryItem surveillanceQueryItem = new SurveillanceQueryItem();
|
surveillanceQueryItem.setNativeImg(nativeImg);
|
nativeImg.st_track_id = 1;
|
surveillanceQueryItem.setStTrackId(nativeImg.st_track_id);
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
options.inMutable = true;
|
Bitmap bmp = BitmapFactory.decodeByteArray(nativeImg.image, 0, nativeImg.image.length, options);
|
Canvas canvas1 = new Canvas(bmp);
|
|
surveillanceQueryItem.setBitmap(bmp);
|
surveillanceQueryItem.setWidth("100");
|
surveillanceQueryItem.setHeight("100");
|
bitmapList.add(surveillanceQueryItem);
|
|
|
SurveillanceMng.getInstance().addBitmap(bitmapList, nativeImg.image, 0, CommonVariables.Camera.IN+"", nativeImg.image);
|
}
|
|
}
|
FSDK.FreeImage(RotatedImage);
|
faceLock.unlock();
|
|
int shift = (int)(22 * MainActivity.sDensity);
|
|
for (int i=0; i<face_count[0]; ++i) {
|
canvas.drawRect(mFacePositions[i].x1, mFacePositions[i].y1, mFacePositions[i].x2, mFacePositions[i].y2, mPaintBlueTransparent);
|
|
boolean named = false;
|
if (IDs[i] != -1) {
|
String names[] = new String[1];
|
FSDK.GetAllNames(mTracker, IDs[i], names, 1024);
|
if (names[0] != null && names[0].length() > 0) {
|
canvas.drawText(names[0], (mFacePositions[i].x1+mFacePositions[i].x2)/2, mFacePositions[i].y2+shift, mPaintBlue);
|
named = true;
|
}
|
}
|
if (!named) {
|
canvas.drawText("Tap to name", (mFacePositions[i].x1+mFacePositions[i].x2)/2, mFacePositions[i].y2+shift, mPaintGreen);
|
}
|
}
|
|
super.onDraw(canvas);
|
}
|
|
|
@Override
|
public boolean onTouchEvent(MotionEvent event) { //NOTE: the method can be implemented in Preview class
|
switch (event.getAction()) {
|
case MotionEvent.ACTION_DOWN:
|
int x = (int)event.getX();
|
int y = (int)event.getY();
|
|
faceLock.lock();
|
FaceRectangle rects[] = new FaceRectangle[MAX_FACES];
|
long IDs[] = new long[MAX_FACES];
|
for (int i=0; i<MAX_FACES; ++i) {
|
rects[i] = new FaceRectangle();
|
rects[i].x1 = mFacePositions[i].x1;
|
rects[i].y1 = mFacePositions[i].y1;
|
rects[i].x2 = mFacePositions[i].x2;
|
rects[i].y2 = mFacePositions[i].y2;
|
IDs[i] = mIDs[i];
|
}
|
faceLock.unlock();
|
|
for (int i=0; i<MAX_FACES; ++i) {
|
if (rects[i] != null && rects[i].x1 <= x && x <= rects[i].x2 && rects[i].y1 <= y && y <= rects[i].y2 + 30) {
|
mTouchedID = IDs[i];
|
|
mTouchedIndex = i;
|
|
final EditText input = new EditText(mContext);
|
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
builder.setMessage("Enter person's name" )
|
.setView(input)
|
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
@Override public void onClick(DialogInterface dialogInterface, int j) {
|
FSDK.LockID(mTracker, mTouchedID);
|
FSDK.SetName(mTracker, mTouchedID, input.getText().toString());
|
FSDK.UnlockID(mTracker, mTouchedID);
|
mTouchedIndex = -1;
|
}
|
})
|
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
@Override public void onClick(DialogInterface dialogInterface, int j) {
|
mTouchedIndex = -1;
|
}
|
})
|
.setCancelable(false)
|
.show();
|
|
break;
|
}
|
}
|
}
|
return true;
|
}
|
|
static public void decodeYUV420SP(byte[] rgb, byte[] yuv420sp, int width, int height) {
|
final int frameSize = width * height;
|
int yp = 0;
|
for (int j = 0; j < height; j++) {
|
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
|
for (int i = 0; i < width; i++) {
|
int y = (0xff & ((int) yuv420sp[yp])) - 16;
|
if (y < 0) y = 0;
|
if ((i & 1) == 0) {
|
v = (0xff & yuv420sp[uvp++]) - 128;
|
u = (0xff & yuv420sp[uvp++]) - 128;
|
}
|
int y1192 = 1192 * y;
|
int r = (y1192 + 1634 * v);
|
int g = (y1192 - 833 * v - 400 * u);
|
int b = (y1192 + 2066 * u);
|
if (r < 0) r = 0; else if (r > 262143) r = 262143;
|
if (g < 0) g = 0; else if (g > 262143) g = 262143;
|
if (b < 0) b = 0; else if (b > 262143) b = 262143;
|
|
rgb[3*yp] = (byte) ((r >> 10) & 0xff);
|
rgb[3*yp+1] = (byte) ((g >> 10) & 0xff);
|
rgb[3*yp+2] = (byte) ((b >> 10) & 0xff);
|
++yp;
|
}
|
}
|
}
|
}
|
|
class Preview extends SurfaceView implements SurfaceHolder.Callback {
|
Context mContext;
|
SurfaceHolder mHolder;
|
Camera mCamera;
|
ProcessImageAndDrawResults mDraw;
|
boolean mFinished;
|
|
Preview(Context context, ProcessImageAndDrawResults draw) {
|
super(context);
|
mContext = context;
|
mDraw = draw;
|
|
mHolder = getHolder();
|
mHolder.addCallback(this);
|
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
}
|
|
public void surfaceCreated(SurfaceHolder holder) {
|
mFinished = false;
|
|
int cameraId = 0;
|
boolean frontCameraFound = false;
|
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
|
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
|
Camera.getCameraInfo(i, cameraInfo);
|
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
cameraId = i;
|
frontCameraFound = true;
|
}
|
}
|
//If authorisation not granted for camera
|
if (ContextCompat.checkSelfPermission(MainActivity.getInstance(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
|
//ask for authorisation
|
ActivityCompat.requestPermissions(MainActivity.getInstance(), new String[]{Manifest.permission.CAMERA}, 50);
|
|
if (frontCameraFound) {
|
mCamera = Camera.open(cameraId);
|
} else {
|
mCamera = Camera.open();
|
}
|
|
|
try {
|
mCamera.setPreviewDisplay(holder);
|
|
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
|
public void onPreviewFrame(byte[] data, Camera camera) {
|
if ( (mDraw == null) || mFinished )
|
return;
|
|
if (mDraw.mYUVData == null) {
|
Camera.Parameters params = camera.getParameters();
|
mDraw.mImageWidth = params.getPreviewSize().width;
|
mDraw.mImageHeight = params.getPreviewSize().height;
|
mDraw.mRGBData = new byte[3 * mDraw.mImageWidth * mDraw.mImageHeight];
|
mDraw.mYUVData = new byte[data.length];
|
}
|
|
System.arraycopy(data, 0, mDraw.mYUVData, 0, data.length);
|
mDraw.invalidate();
|
}
|
});
|
}
|
catch (Exception exception) {
|
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
builder.setMessage("Cannot open camera" )
|
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
@Override
|
public void onClick(DialogInterface dialogInterface, int i) {
|
android.os.Process.killProcess(android.os.Process.myPid());
|
}
|
})
|
.show();
|
if (mCamera != null) {
|
mCamera.release();
|
mCamera = null;
|
}
|
}
|
}
|
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
mFinished = true;
|
if (mCamera != null) {
|
mCamera.setPreviewCallback(null);
|
mCamera.stopPreview();
|
mCamera.release();
|
mCamera = null;
|
}
|
}
|
|
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
if (mCamera == null) return;
|
|
Camera.Parameters parameters = mCamera.getParameters();
|
|
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
|
parameters.set("orientation", "portrait");
|
mCamera.setDisplayOrientation(90);
|
mDraw.rotated = true;
|
} else {
|
parameters.set("orientation", "landscape");
|
mCamera.setDisplayOrientation(0);
|
}
|
List<Camera.Size> supportedSizes = parameters.getSupportedPreviewSizes();
|
int width = 0;
|
int height = 0;
|
System.out.println("surfaceChanged");
|
for (Camera.Size s: supportedSizes) {
|
if ((width - 640)*(width - 640) + (height - 480)*(height - 480) >
|
(s.width - 640)*(s.width - 640) + (s.height - 480)*(s.height - 480)) {
|
width = s.width;
|
height = s.height;
|
}
|
}
|
|
try {
|
if (width*height > 0) {
|
parameters.setPreviewSize(width, height);
|
}
|
parameters.setSceneMode(Camera.Parameters.SCENE_MODE_PORTRAIT);
|
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
|
mCamera.setParameters(parameters);
|
} catch (Exception ex) {
|
}
|
mCamera.startPreview();
|
|
parameters = mCamera.getParameters();
|
Camera.Size previewSize = parameters.getPreviewSize();
|
makeResizeForCameraAspect(1.0f / ((1.0f * previewSize.width) / previewSize.height));
|
}
|
|
private void makeResizeForCameraAspect(float cameraAspectRatio){
|
ViewGroup.LayoutParams layoutParams = this.getLayoutParams();
|
int matchParentWidth = this.getWidth();
|
int newHeight = (int)(matchParentWidth/cameraAspectRatio);
|
if (newHeight != layoutParams.height) {
|
layoutParams.height = newHeight;
|
layoutParams.width = matchParentWidth;
|
this.setLayoutParams(layoutParams);
|
this.invalidate();
|
}
|
}
|
}
|