package com.marshalchen.common.uimodule.shapeimageview.shader;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import com.marshalchen.common.uimodule.R;
@SuppressWarnings("WeakerAccess")
public abstract class ShaderHelper {
private final static int ALPHA_MAX = 255;
protected int viewWidth;
protected int viewHeight;
protected int borderColor = Color.BLACK;
protected int borderWidth = 0;
protected float borderAlpha = 1f;
protected boolean square = false;
protected final Paint borderPaint;
protected final Paint imagePaint;
protected BitmapShader shader;
protected Drawable drawable;
protected final Matrix matrix = new Matrix();
public ShaderHelper() {
borderPaint = new Paint();
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setAntiAlias(true);
imagePaint = new Paint();
imagePaint.setAntiAlias(true);
}
public abstract void draw(Canvas canvas, Paint imagePaint, Paint borderPaint);
public abstract void reset();
@SuppressWarnings("UnusedParameters")
public abstract void calculate(int bitmapWidth, int bitmapHeight, float width, float height, float scale, float translateX, float translateY);
@SuppressWarnings("SameParameterValue")
protected final int dpToPx(DisplayMetrics displayMetrics, int dp) {
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
public boolean isSquare() {
return square;
}
public void init(Context context, AttributeSet attrs, int defStyle) {
if(attrs != null){
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShaderImageView, defStyle, 0);
borderColor = typedArray.getColor(R.styleable.ShaderImageView_borderColor, borderColor);
borderWidth = typedArray.getDimensionPixelSize(R.styleable.ShaderImageView_borderWidth, borderWidth);
borderAlpha = typedArray.getFloat(R.styleable.ShaderImageView_borderAlpha, borderAlpha);
square = typedArray.getBoolean(R.styleable.ShaderImageView_square, square);
typedArray.recycle();
}
borderPaint.setColor(borderColor);
borderPaint.setAlpha(Float.valueOf(borderAlpha * ALPHA_MAX).intValue());
borderPaint.setStrokeWidth(borderWidth);
}
public boolean onDraw(Canvas canvas) {
if (shader == null) {
createShader();
}
if (shader != null && viewWidth > 0 && viewHeight > 0) {
draw(canvas, imagePaint, borderPaint);
return true;
}
return false;
}
public void onSizeChanged(int width, int height) {
viewWidth = width;
viewHeight = height;
if(isSquare()) {
viewWidth = viewHeight = Math.min(width, height);
}
if(shader != null) {
calculateDrawableSizes();
}
}
public Bitmap calculateDrawableSizes() {
Bitmap bitmap = getBitmap();
if(bitmap != null) {
int bitmapWidth = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
if(bitmapWidth > 0 && bitmapHeight > 0) {
float width = Math.round(viewWidth - 2f * borderWidth);
float height = Math.round(viewHeight - 2f * borderWidth);
float scale;
float translateX = 0;
float translateY = 0;
if (bitmapWidth * height > width * bitmapHeight) {
scale = height / bitmapHeight;
translateX = Math.round((width/scale - bitmapWidth) / 2f);
} else {
scale = width / (float) bitmapWidth;
translateY = Math.round((height/scale - bitmapHeight) / 2f);
}
matrix.setScale(scale, scale);
matrix.preTranslate(translateX, translateY);
matrix.postTranslate(borderWidth, borderWidth);
calculate(bitmapWidth, bitmapHeight, width, height, scale, translateX, translateY);
return bitmap;
}
}
reset();
return null;
}
public final void onImageDrawableReset(Drawable drawable) {
this.drawable = drawable;
shader = null;
imagePaint.setShader(null);
}
protected void createShader() {
Bitmap bitmap = calculateDrawableSizes();
if(bitmap != null && bitmap.getWidth() > 0 && bitmap.getHeight() > 0) {
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
imagePaint.setShader(shader);
}
}
protected Bitmap getBitmap() {
Bitmap bitmap = null;
if(drawable != null) {
if(drawable instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) drawable).getBitmap();
}
}
return bitmap;
}
}