Skip to content

Instantly share code, notes, and snippets.

@aligkts
Last active June 16, 2019 15:02
Show Gist options
  • Save aligkts/69d0525131dee2002811a625ad31adb8 to your computer and use it in GitHub Desktop.
Save aligkts/69d0525131dee2002811a625ad31adb8 to your computer and use it in GitHub Desktop.
class GraphicOverlay(context: Context, attrs: AttributeSet) : View(context, attrs) {
private val mLock = Any()
private var mPreviewWidth: Int = 0
private var mWidthScaleFactor = 1.0f
private var mPreviewHeight: Int = 0
private var mHeightScaleFactor = 1.0f
private var mFacing = CameraSource.CAMERA_FACING_BACK
private val mGraphics = HashSet<Graphic>()
/**
* Base class for a custom graphics object to be rendered within the graphic overlay. Subclass
* this and implement the [Graphic.draw] method to define the
* graphics element. Add instances to the overlay using [GraphicOverlay.add].
*/
abstract class Graphic(private val mOverlay: GraphicOverlay) {
/**
* Draw the graphic on the supplied canvas. Drawing should use the following methods to
* convert to view coordinates for the graphics that are drawn:
*
* 1. [Graphic.scaleX] and [Graphic.scaleY] adjust the size of
* the supplied value from the preview scale to the view scale.
* 1. [Graphic.translateX] and [Graphic.translateY] adjust the
* coordinate from the preview's coordinate system to the view coordinate system.
*
*
* @param canvas drawing canvas
*/
abstract fun draw(canvas: Canvas)
/**
* Adjusts a horizontal value of the supplied value from the preview scale to the view
* scale.
*/
fun scaleX(horizontal: Float): Float {
return horizontal * mOverlay.mWidthScaleFactor
}
/**
* Adjusts a vertical value of the supplied value from the preview scale to the view scale.
*/
fun scaleY(vertical: Float): Float {
return vertical * mOverlay.mHeightScaleFactor
}
/**
* Adjusts the x coordinate from the preview's coordinate system to the view coordinate
* system.
*/
fun translateX(x: Float): Float {
return if (mOverlay.mFacing == CameraSource.CAMERA_FACING_FRONT) {
mOverlay.width - scaleX(x)
} else {
scaleX(x)
}
}
/**
* Adjusts the y coordinate from the preview's coordinate system to the view coordinate
* system.
*/
fun translateY(y: Float): Float {
return scaleY(y)
}
fun postInvalidate() {
mOverlay.postInvalidate()
}
}
/**
* Removes all graphics from the overlay.
*/
fun clear() {
synchronized(mLock) {
mGraphics.clear()
}
postInvalidate()
}
/**
* Adds a graphic to the overlay.
*/
fun add(graphic: Graphic) {
synchronized(mLock) {
mGraphics.add(graphic)
}
postInvalidate()
}
/**
* Removes a graphic from the overlay.
*/
fun remove(graphic: Graphic) {
synchronized(mLock) {
mGraphics.remove(graphic)
}
postInvalidate()
}
/**
* Sets the camera attributes for size and facing direction, which informs how to transform
* image coordinates later.
*/
fun setCameraInfo(previewWidth: Int, previewHeight: Int, facing: Int) {
synchronized(mLock) {
mPreviewWidth = previewWidth
mPreviewHeight = previewHeight
mFacing = facing
}
postInvalidate()
}
/**
* Draws the overlay with its associated graphic objects.
*/
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
synchronized(mLock) {
if (mPreviewWidth != 0 && mPreviewHeight != 0) {
mWidthScaleFactor = canvas.width.toFloat() / mPreviewWidth.toFloat()
mHeightScaleFactor = canvas.height.toFloat() / mPreviewHeight.toFloat()
}
for (graphic in mGraphics) {
graphic.draw(canvas)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment