As you know, the preview size of the camera is configurable at the settings menu. This configurable size specifies the graphicOverlay
dimensions.
On the other hand, the aspect ratio of the CameraSourcePreview
(i.e. preview_view
in activity_vision_live_preview.xml
) which is shown on the screen, does not necessarily equal to the ratio of the graphicOverlay
. Because depends on the size of the phone's screen and the height that the parent ConstraintLayout
allows occupying.
So, in the preview, based on the difference between the aspect ratio of graphicOverlay
and preview_view
, some part of the graphicOverlay
might not be shown horizontally or vertically.
There are some parameters inside GraphicOverlay
that can help us to adjust the left and top of the barcode's boundingBox in such a way that they start from 0 in the visible area.
First of all, they should be accessible out of the GraphicOverlay
class. So, it's just enough to write a getter method for them:
GraphicOverlay.java
public class GraphicOverlay extends View {
...
/**
* The factor of overlay View size to image size. Anything in the image coordinates need to be
* scaled by this amount to fit with the area of overlay View.
*/
public float getScaleFactor() {
return scaleFactor;
}
/**
* The number of vertical pixels needed to be cropped on each side to fit the image with the
* area of overlay View after scaling.
*/
public float getPostScaleHeightOffset() {
return postScaleHeightOffset;
}
/**
* The number of horizontal pixels needed to be cropped on each side to fit the image with the
* area of overlay View after scaling.
*/
public float getPostScaleWidthOffset() {
return postScaleWidthOffset;
}
}
Now, it is possible to calculate the left and top difference gap using these parameters like the following:
BarcodeScannerProcessor.kt
class BarcodeScannerProcessor(
context: Context
) : VisionProcessorBase<List<Barcode>>(context) {
...
override fun onSuccess(barcodes: List<Barcode>, graphicOverlay: GraphicOverlay) {
if (barcodes.isEmpty()) {
Log.v(MANUAL_TESTING_LOG, "No barcode has been detected")
}
val leftDiff = graphicOverlay.run { postScaleWidthOffset / scaleFactor }.toInt()
val topDiff = graphicOverlay.run { postScaleHeightOffset / scaleFactor }.toInt()
for (i in barcodes.indices) {
val barcode = barcodes[i]
val color = Color.RED
val text = "left: ${barcode.boundingBox!!.left - leftDiff} top: ${barcode.boundingBox!!.top - topDiff}"
graphicOverlay.add(MyBarcodeGraphic(graphicOverlay, barcode, text, color))
logExtrasForTesting(barcode)
}
}
...
}
Visual Result:
Here is the visual result of the output. As it's obvious in the pictures, the gap between both left & top of the barcode
and the left and top of the visible area is started from 0. In the case of the left picture, the graphicOverlay
is set to the size of 480x640
(aspect ratio ≈ 1.3334) and for the right one 360x640
(aspect ratio ≈ 1.7778). In both cases, on my phone, the CameraSourcePreview
has a steady size of 1440x2056
pixels (aspect ratio ≈ 1.4278), so it means that the calculation truly reflected the position of the barcode
in the visible area.
(note that the aspect ratio of the visible area in one experiment is lower than that of graphicOverlay
, and in another experiment, greater: 1.3334 < 1.4278 < 1.7778. So, the left values and top values are adjusted respectively.)
