package hu.autsoft.androidapidemos.ocr;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import com.google.android.gms.vision.CameraSource;
import java.util.HashSet;
import java.util.Set;
public class GraphicOverlay<T extends GraphicOverlay.Graphic> extends View {
private final Object mLock = new Object();
private int mPreviewWidth;
private float mWidthScaleFactor = 1.0f;
private int mPreviewHeight;
private float mHeightScaleFactor = 1.0f;
private int mFacing = CameraSource.CAMERA_FACING_BACK;
private Set<T> mGraphics = new HashSet<>();
public static abstract class Graphic {
private GraphicOverlay mOverlay;
public Graphic(GraphicOverlay overlay) {
mOverlay = overlay;
}
public abstract void draw(Canvas canvas);
/**
* Returns true if the supplied coordinates are within this graphic.
*/
public abstract boolean contains(float x, float y);
/**
* Adjusts a horizontal value of the supplied value from the preview scale to the view
* scale.
*/
public float scaleX(float horizontal) {
return horizontal * mOverlay.mWidthScaleFactor;
}
/**
* Adjusts a vertical value of the supplied value from the preview scale to the view scale.
*/
public float scaleY(float vertical) {
return vertical * mOverlay.mHeightScaleFactor;
}
/**
* Adjusts the x coordinate from the preview's coordinate system to the view coordinate
* system.
*/
public float translateX(float x) {
if (mOverlay.mFacing == CameraSource.CAMERA_FACING_FRONT) {
return mOverlay.getWidth() - scaleX(x);
} else {
return scaleX(x);
}
}
/**
* Adjusts the y coordinate from the preview's coordinate system to the view coordinate
* system.
*/
public float translateY(float y) {
return scaleY(y);
}
public void postInvalidate() {
mOverlay.postInvalidate();
}
}
public GraphicOverlay(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* Removes all graphics from the overlay.
*/
public void clear() {
synchronized (mLock) {
mGraphics.clear();
}
postInvalidate();
}
/**
* Adds a graphic to the overlay.
*/
public void add(T graphic) {
synchronized (mLock) {
mGraphics.add(graphic);
}
postInvalidate();
}
/**
* Removes a graphic from the overlay.
*/
public void remove(T graphic) {
synchronized (mLock) {
mGraphics.remove(graphic);
}
postInvalidate();
}
/**
* Returns the first graphic, if any, that exists at the provided absolute screen coordinates.
* These coordinates will be offset by the relative screen position of this view.
* @return First graphic containing the point, or null if no text is detected.
*/
public T getGraphicAtLocation(float rawX, float rawY) {
synchronized (mLock) {
// Get the position of this View so the raw location can be offset relative to the view.
int[] location = new int[2];
this.getLocationOnScreen(location);
for (T graphic : mGraphics) {
if (graphic.contains(rawX - location[0], rawY - location[1])) {
return graphic;
}
}
return null;
}
}
/**
* Sets the camera attributes for size and facing direction, which informs how to transform
* image coordinates later.
*/
public void setCameraInfo(int previewWidth, int previewHeight, int facing) {
synchronized (mLock) {
mPreviewWidth = previewWidth;
mPreviewHeight = previewHeight;
mFacing = facing;
}
postInvalidate();
}
/**
* Draws the overlay with its associated graphic objects.
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
synchronized (mLock) {
if ((mPreviewWidth != 0) && (mPreviewHeight != 0)) {
mWidthScaleFactor = (float) canvas.getWidth() / (float) mPreviewWidth;
mHeightScaleFactor = (float) canvas.getHeight() / (float) mPreviewHeight;
}
for (Graphic graphic : mGraphics) {
graphic.draw(canvas);
}
}
}
}