Last active
July 24, 2020 18:02
-
-
Save doomSDey/cf9b2a715846f1e7a9e1686f0b49ede3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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