Skip to content

Instantly share code, notes, and snippets.

@doomSDey
Last active July 24, 2020 18:02
Show Gist options
  • Save doomSDey/cf9b2a715846f1e7a9e1686f0b49ede3 to your computer and use it in GitHub Desktop.
Save doomSDey/cf9b2a715846f1e7a9e1686f0b49ede3 to your computer and use it in GitHub Desktop.
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
TextView textView;
PreviewView mCameraView;
SurfaceHolder holder;
SurfaceView surfaceView;
Canvas canvas;
Paint paint;
int cameraHeight, cameraWidth, xOffset, yOffset, boxWidth, boxHeight;
private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
private ExecutorService executor = Executors.newSingleThreadExecutor();
/**
*Responsible for converting the rotation degrees from CameraX into the one compatible with Firebase ML
*/
private int degreesToFirebaseRotation(int degrees) {
switch (degrees) {
case 0:
return FirebaseVisionImageMetadata.ROTATION_0;
case 90:
return FirebaseVisionImageMetadata.ROTATION_90;
case 180:
return FirebaseVisionImageMetadata.ROTATION_180;
case 270:
return FirebaseVisionImageMetadata.ROTATION_270;
default:
throw new IllegalArgumentException(
"Rotation must be 0, 90, 180, or 270.");
}
}
/**
* Starting Camera
*/
void startCamera(){
mCameraView = findViewById(R.id.previewView);
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(new Runnable() {
@Override
public void run() {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
MainActivity.this.bindPreview(cameraProvider);
} catch (ExecutionException | InterruptedException e) {
// No errors need to be handled for this Future.
// This should never be reached.
}
}
}, ContextCompat.getMainExecutor(this));
}
/**
*
* Binding to camera
*/
private void bindPreview(ProcessCameraProvider cameraProvider) {
Preview preview = new Preview.Builder()
.build();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
preview.setSurfaceProvider(mCameraView.createSurfaceProvider());
//Image Analysis Function
//Set static size according to your device or write a dynamic function for it
ImageAnalysis imageAnalysis =
new ImageAnalysis.Builder()
.setTargetResolution(new Size(720, 1488))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
@SuppressLint("UnsafeExperimentalUsageError")
@Override
public void analyze(@NonNull ImageProxy image) {
//changing normal degrees into Firebase rotation
int rotationDegrees = degreesToFirebaseRotation(image.getImageInfo().getRotationDegrees());
if (image == null || image.getImage() == null) {
return;
}
//Getting a FirebaseVisionImage object using the Image object and rotationDegrees
final Image mediaImage = image.getImage();
FirebaseVisionImage images = FirebaseVisionImage.fromMediaImage(mediaImage, rotationDegrees);
//Getting bitmap from FirebaseVisionImage Object
Bitmap bmp=images.getBitmap();
//Getting the values for cropping
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = bmp.getHeight();
int width = bmp.getWidth();
int left, right, top, bottom, diameter;
diameter = width;
if (height < width) {
diameter = height;
}
int offset = (int) (0.05 * diameter);
diameter -= offset;
left = width / 2 - diameter / 3;
top = height / 2 - diameter / 3;
right = width / 2 + diameter / 3;
bottom = height / 2 + diameter / 3;
xOffset = left;
yOffset = top;
//Creating new cropped bitmap
Bitmap bitmap = Bitmap.createBitmap(bmp, left, top, boxWidth, boxHeight);
//initializing FirebaseVisionTextRecognizer object
FirebaseVisionTextRecognizer detector = FirebaseVision.getInstance()
.getOnDeviceTextRecognizer();
//Passing FirebaseVisionImage Object created from the cropped bitmap
Task<FirebaseVisionText> result = detector.processImage(FirebaseVisionImage.fromBitmap(bitmap))
.addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
@Override
public void onSuccess(FirebaseVisionText firebaseVisionText) {
// Task completed successfully
// ...
textView=findViewById(R.id.text);
//getting decoded text
String text=firebaseVisionText.getText();
//Setting the decoded text in the texttview
textView.setText(text);
//for getting blocks and line elements
for (FirebaseVisionText.TextBlock block: firebaseVisionText.getTextBlocks()) {
String blockText = block.getText();
for (FirebaseVisionText.Line line: block.getLines()) {
String lineText = line.getText();
for (FirebaseVisionText.Element element: line.getElements()) {
String elementText = element.getText();
}
}
}
image.close();
}
})
.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Task failed with an exception
// ...
Log.e("Error",e.toString());
image.close();
}
});
}
});
Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, imageAnalysis,preview);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Start Camera
startCamera();
//Create the bounding box
surfaceView = findViewById(R.id.overlay);
surfaceView.setZOrderOnTop(true);
holder = surfaceView.getHolder();
holder.setFormat(PixelFormat.TRANSPARENT);
holder.addCallback(this);
}
/**
*
* For drawing the rectangular box
*/
private void DrawFocusRect(int color) {
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = mCameraView.getHeight();
int width = mCameraView.getWidth();
//cameraHeight = height;
//cameraWidth = width;
int left, right, top, bottom, diameter;
diameter = width;
if (height < width) {
diameter = height;
}
int offset = (int) (0.05 * diameter);
diameter -= offset;
canvas = holder.lockCanvas();
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
//border's properties
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(color);
paint.setStrokeWidth(5);
left = width / 2 - diameter / 3;
top = height / 2 - diameter / 3;
right = width / 2 + diameter / 3;
bottom = height / 2 + diameter / 3;
xOffset = left;
yOffset = top;
boxHeight = bottom - top;
boxWidth = right - left;
//Changing the value of x in diameter/x will change the size of the box ; inversely proportionate to x
canvas.drawRect(left, top, right, bottom, paint);
holder.unlockCanvasAndPost(canvas);
}
/**
* Callback functions for the surface Holder
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//Drawing rectangle
DrawFocusRect(Color.parseColor("#b3dabb"));
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment