Created
September 26, 2018 07:07
-
-
Save nagendrababu143/a985f9a55b3b62e413074b1dbbe27d1d 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
/* | |
* Copyright (C) The Android Open Source Project | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.google.android.gms.samples.vision.ocrreader.ui.camera; | |
import android.content.Context; | |
import android.graphics.Canvas; | |
import android.graphics.Rect; | |
import android.graphics.RectF; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import com.google.android.gms.vision.CameraSource; | |
import java.util.HashSet; | |
import java.util.Set; | |
/** | |
* A view which renders a series of custom graphics to be overlaid on top of an associated preview | |
* (i.e., the camera preview). The creator can add graphics objects, update the objects, and remove | |
* them, triggering the appropriate drawing and invalidation within the view.<p> | |
* | |
* Supports scaling and mirroring of the graphics relative the camera's preview properties. The | |
* idea is that detection items are expressed in terms of a preview size, but need to be scaled up | |
* to the full view size, and also mirrored in the case of the front-facing camera.<p> | |
* | |
* Associated {@link Graphic} items should use the following methods to convert to view coordinates | |
* for the graphics that are drawn: | |
* <ol> | |
* <li>{@link Graphic#scaleX(float)} and {@link Graphic#scaleY(float)} adjust the size of the | |
* supplied value from the preview scale to the view scale.</li> | |
* <li>{@link Graphic#translateX(float)} and {@link Graphic#translateY(float)} adjust the coordinate | |
* from the preview's coordinate system to the view coordinate system.</li> | |
* </ol> | |
*/ | |
public class GraphicOverlay<T extends GraphicOverlay.Graphic> extends View { | |
private final Object lock = new Object(); | |
private int previewWidth; | |
private float widthScaleFactor = 1.0f; | |
private int previewHeight; | |
private float heightScaleFactor = 1.0f; | |
private int facing = CameraSource.CAMERA_FACING_BACK; | |
private Set<T> graphics = new HashSet<>(); | |
/** | |
* Base class for a custom graphics object to be rendered within the graphic overlay. Subclass | |
* this and implement the {@link Graphic#draw(Canvas)} method to define the | |
* graphics element. Add instances to the overlay using {@link GraphicOverlay#add(Graphic)}. | |
*/ | |
public static abstract class Graphic { | |
private GraphicOverlay mOverlay; | |
public Graphic(GraphicOverlay overlay) { | |
mOverlay = overlay; | |
} | |
/** | |
* Draw the graphic on the supplied canvas. Drawing should use the following methods to | |
* convert to view coordinates for the graphics that are drawn: | |
* <ol> | |
* <li>{@link Graphic#scaleX(float)} and {@link Graphic#scaleY(float)} adjust the size of | |
* the supplied value from the preview scale to the view scale.</li> | |
* <li>{@link Graphic#translateX(float)} and {@link Graphic#translateY(float)} adjust the | |
* coordinate from the preview's coordinate system to the view coordinate system.</li> | |
* </ol> | |
* | |
* @param canvas drawing canvas | |
*/ | |
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.widthScaleFactor; | |
} | |
/** | |
* Adjusts a vertical value of the supplied value from the preview scale to the view scale. | |
*/ | |
public float scaleY(float vertical) { | |
return vertical * mOverlay.heightScaleFactor; | |
} | |
/** | |
* Adjusts the x coordinate from the preview's coordinate system to the view coordinate | |
* system. | |
*/ | |
public float translateX(float x) { | |
if (mOverlay.facing == 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); | |
} | |
/** | |
* Returns a RectF in which the left and right parameters of the provided Rect are adjusted | |
* by translateX, and the top and bottom are adjusted by translateY. | |
*/ | |
public RectF translateRect(RectF inputRect) { | |
RectF returnRect = new RectF(); | |
returnRect.left = translateX(inputRect.left); | |
returnRect.top = translateY(inputRect.top); | |
returnRect.right = translateX(inputRect.right); | |
returnRect.bottom = translateY(inputRect.bottom); | |
return returnRect; | |
} | |
public void postInvalidate() { | |
mOverlay.postInvalidate(); | |
} | |
} | |
public GraphicOverlay(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
/** | |
* Removes all graphics from the overlay. | |
*/ | |
public void clear() { | |
synchronized (lock) { | |
graphics.clear(); | |
} | |
postInvalidate(); | |
} | |
/** | |
* Adds a graphic to the overlay. | |
*/ | |
public void add(T graphic) { | |
synchronized (lock) { | |
graphics.add(graphic); | |
} | |
postInvalidate(); | |
} | |
/** | |
* Removes a graphic from the overlay. | |
*/ | |
public void remove(T graphic) { | |
synchronized (lock) { | |
graphics.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 (lock) { | |
// 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 : graphics) { | |
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 (lock) { | |
this.previewWidth = previewWidth; | |
this.previewHeight = previewHeight; | |
this.facing = facing; | |
} | |
postInvalidate(); | |
} | |
/** | |
* Draws the overlay with its associated graphic objects. | |
*/ | |
@Override | |
protected void onDraw(Canvas canvas) { | |
super.onDraw(canvas); | |
synchronized (lock) { | |
if ((previewWidth != 0) && (previewHeight != 0)) { | |
widthScaleFactor = (float) canvas.getWidth() / (float) previewWidth; | |
heightScaleFactor = (float) canvas.getHeight() / (float) previewHeight; | |
} | |
for (Graphic graphic : graphics) { | |
graphic.draw(canvas); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment