Skip to content

Instantly share code, notes, and snippets.

@AlexMeuer
Created August 9, 2017 11:01
Show Gist options
  • Save AlexMeuer/ac2480f9388cfd6888d98c2c1228515c to your computer and use it in GitHub Desktop.
Save AlexMeuer/ac2480f9388cfd6888d98c2c1228515c to your computer and use it in GitHub Desktop.
Simple Drawable extension to allow highlighting regions of a single image. Also allows an overlay to be drawn on top of the selection (I've use a bitmap for the overlay, but using a color instead is straightforward and follows the same technique as darkening the surrounding area).
package foo.bar;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.BitmapDrawable;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* Drawable which can highlight a selection area and apply an optional overlay.
*/
public class HighlightableBitmapDrawable extends BitmapDrawable {
private Rect mSelection;
private Bitmap mOverlay; // bitmap to be overlaid on top of selection area
private final int mColorRes;
/**
* @param drawable The underlying image.
* @param darkenColor The color to darken the underlying image with.
*/
public HighlightableBitmapDrawable(@NonNull Resources resources, @DrawableRes int drawable, @ColorRes int darkenColor) {
super(resources, BitmapFactory.decodeResource(resources, drawable));
mColorRes = darkenColor;
}
/**
* Highlights the given region.
* @param region The region to highlight. Can be null to clear current selection.
*/
public void selectRegion(@Nullable Rect region) {
mSelection = region;
}
public void selectRegion(int left, int top, int right, int bottom) {
selectRegion(new Rect(left, top, right, bottom));
}
public void clearSelection() {
selectRegion(null);
}
/**
* Sets an overlay image to be drawn inside the selection bounds.
* @param overlay The bitmap to use. Can be null to remove current overlay.
*/
public void setOverlay(@Nullable Bitmap overlay) {
mOverlay = overlay;
}
public void setOverlay(@NonNull Resources resources, @DrawableRes int overlay) {
setOverlay(BitmapFactory.decodeResource(resources, overlay));
}
public void clearOverlay() {
setOverlay(null);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas); // Draw the underlying image.
if (null != mSelection) {
if (null != mOverlay) {
// If we have an overlay, paint it on top of the selected area.
// (This must be done BEFORE clipping the canvas or it won't show.)
canvas.drawBitmap(mOverlay, null, mSelection, null);
}
// If we have a selection, darken its surroundings.
canvas.clipRect(mSelection, Region.Op.DIFFERENCE);
//noinspection ResourceAsColor
canvas.drawColor(mColorRes);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment