First:we should download a SDK package from internet.it’s called Touch3D
接下来主要是是向大家介绍这个SDK 是如何集成到我们的应用当中去。
mCameraEventListener = new CameraEventListener();
mImageRotationListener = new RotationListener();
// Create camera wrapper to handle camera functionality
mCameraWrapper = new CameraWrapper();
// Create touchless wrapper to handle gesture functionality
mTouchlessA3DWrapper = new TouchlessA3DWrapper(new TouchlessEventListener());
// Create helper for managing camera image rotation.
mImageRotationHelper = new ImageRotationHelper(this);
在oncreat中我们先把mTouchlessA3DWrapper对象先实例化。
private class TouchlessEventListener implements TouchlessA3DWrapper.TouchlessEventListener {
@Override
public void openHandFound() {
// Dispatch UI updates to UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
mPoseView.showOpenHand();
}
});
}
@Override
public void closedHandFound() {
// Dispatch UI updates to UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
mPoseView.showClosedHand();
}
});
}
@Override
public void pinchFound() {
// Dispatch UI updates to UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
mPoseView.showPinch();
}
});
}
@Override
public void thumbsUpFound() {
// Dispatch UI updates to UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
mPoseView.showThumbsUp();
}
});
}
@Override
public void poseLost() {
// Dispatch UI updates to UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
mPoseView.hideHand();
}
});
}
@Override
public void onError(final Exception e) {
Log.e(LOG_TAG, "TouchlessEventListener.onError: ", e);
// Dispatch event to main queue to update UI
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(TouchlessWorldActivity.this,
"Error reported from touchless engine. See logs for more info.",
Toast.LENGTH_LONG).show();
}
});
}
}
PoseView是我们自定的view用于显示手势识别成功后显示相应的图片。
CameraWrapper这个类当中主要是封装我们一些操作Camera的一些方法和数据回调。
private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
@Override
public void onImageAvailable(ImageReader imageReader) {
Image image = imageReader.acquireLatestImage();
if (image != null) {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
//Get Y-plane of the YUV_420_888 image.
Image.Plane yPlane = image.getPlanes()[0];
//Copy plane to a new byte array, skipping row stride.
byte[] bytes = copyPlaneDataToPackedByteArray(yPlane, imageWidth, imageHeight);
//Convert timestamp to milliseconds.
long timestampMilliseconds = (long)(image.getTimestamp() / 1e6f);
if(mCameraEventListener != null) {
mCameraEventListener.onFrame(bytes, image.getWidth(), image.getHeight(), timestampMilliseconds);//回调数据给Activity!
}
// Return image to image reader for reuse.
image.close();
}
}
private byte[] copyPlaneDataToPackedByteArray(Image.Plane yPlane, int imageWidth, int imageHeight) {
// Create destination buffer
byte[] bytes = new byte[imageWidth * imageHeight];
ByteBuffer buffer = yPlane.getBuffer();
int strideSkip = yPlane.getRowStride() - imageWidth;
// For every row of destination image
for (int row = 0; buffer.hasRemaining(); row += imageWidth) {
// Copy bytes to destination
buffer.get(bytes, row, imageWidth);
// On last row we mus make sure we have room for the stride skip
if(buffer.hasRemaining()) {
// Skip stride
buffer.position(buffer.position() + strideSkip);
}
}
return bytes;
}
}
TouchlessA3DWrapper这个类主要是封装了一些手势识别的操作!