Skip to content

Android Translate Showcase: Update to use CameraX Beta and PreviewView #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion android/translate-showcase/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

// Add CameraX dependencies
def camerax_version = "1.0.0-alpha05"
def camerax_version = "1.0.0-beta05"
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:1.0.0-alpha12"

// Add ML Kit dependencies
implementation 'com.google.android.gms:play-services-mlkit-text-recognition:16.0.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,52 +25,71 @@ import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import androidx.lifecycle.MutableLiveData
import com.google.android.gms.tasks.Task
import com.google.android.gms.tasks.Tasks
import com.google.mlkit.common.MlKitException
import com.google.mlkit.showcase.translate.util.ImageUtils
import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.text.Text
import com.google.mlkit.vision.text.TextRecognition
import java.lang.Exception


/**
* Analyzes the frames passed in from the camera and returns any detected text within the requested
* crop region.
*/
class TextAnalyzer(
private val context: Context,
private val result: MutableLiveData<String>,
val widthCropPercent: Int,
val heightCropPercent: Int
private val imageCropPercentages: MutableLiveData<Pair<Int, Int>>
) : ImageAnalysis.Analyzer {
private val detector = TextRecognition.getClient()

// Flag to skip analyzing new available frames until previous analysis has finished.
private var isBusy = false

override fun analyze(imageProxy: ImageProxy, imageRotationDegrees: Int) {
@androidx.camera.core.ExperimentalGetImage
override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy.image ?: return
if (isBusy) return

isBusy = true
val rotationDegrees = imageProxy.imageInfo.rotationDegrees

// We requested a setTargetAspectRatio, but it's not guaranteed that's what the camera
// stack is able to support, so we calculate the actual ratio from the first frame to
// know how to appropriately crop the image we want to analyze.
val imageHeight = mediaImage.height
val imageWidth = mediaImage.width

val actualAspectRatio = imageWidth / imageHeight

val convertImageToBitmap = ImageUtils.convertYuv420888ImageToBitmap(mediaImage)
val cropRect = Rect(0, 0, mediaImage.width, mediaImage.height)
val cropRect = Rect(0, 0, imageWidth, imageHeight)

// If the image has a way wider aspect ratio than expected, crop less of the height so we
// don't end up cropping too much of the image. If the image has a way taller aspect ratio
// than expected, we don't have to make any changes to our cropping so we don't handle it
// here.
val currentCropPercentages = imageCropPercentages.value ?: return
if (actualAspectRatio > 3) {
val originalHeightCropPercentage = currentCropPercentages.first
val originalWidthCropPercentage = currentCropPercentages.second
imageCropPercentages.value =
Pair(originalHeightCropPercentage / 2, originalWidthCropPercentage)
}

// If the image is rotated by 90 (or 270) degrees, swap height and width when calculating
// the crop.
val (widthCrop, heightCrop) = when(imageRotationDegrees) {
val cropPercentages = imageCropPercentages.value ?: return
val heightCropPercent = cropPercentages.first
val widthCropPercent = cropPercentages.second
val (widthCrop, heightCrop) = when (rotationDegrees) {
90, 270 -> Pair(heightCropPercent / 100f, widthCropPercent / 100f)
else -> Pair(widthCropPercent / 100f, heightCropPercent / 100f)
}

cropRect.inset(
(mediaImage.width * widthCrop / 2).toInt(),
(mediaImage.height * heightCrop / 2).toInt()
(imageWidth * widthCrop / 2).toInt(),
(imageHeight * heightCrop / 2).toInt()
)
val croppedBitmap =
ImageUtils.rotateAndCrop(convertImageToBitmap, imageRotationDegrees, cropRect);
ImageUtils.rotateAndCrop(convertImageToBitmap, rotationDegrees, cropRect);
recognizeTextOnDevice(InputImage.fromBitmap(croppedBitmap, 0)).addOnCompleteListener {
isBusy = false
imageProxy.close()
}
}

Expand Down
Loading