1+ package com .dvinfosys .widgets .ImageView ;
2+
3+ import android .content .Context ;
4+ import android .content .res .TypedArray ;
5+ import android .graphics .Bitmap ;
6+ import android .graphics .BitmapShader ;
7+ import android .graphics .Canvas ;
8+ import android .graphics .Color ;
9+ import android .graphics .Matrix ;
10+ import android .graphics .Paint ;
11+ import android .graphics .Shader ;
12+ import android .graphics .drawable .BitmapDrawable ;
13+ import android .graphics .drawable .Drawable ;
14+ import android .util .AttributeSet ;
15+ import android .util .DisplayMetrics ;
16+
17+ import com .dvinfosys .widgets .R ;
18+
19+ @ SuppressWarnings ("WeakerAccess" )
20+ public abstract class ShaderHelper {
21+ private final static int ALPHA_MAX = 255 ;
22+
23+ protected int viewWidth ;
24+ protected int viewHeight ;
25+
26+ protected int borderColor = Color .BLACK ;
27+ protected int borderWidth = 0 ;
28+ protected float borderAlpha = 1f ;
29+ protected boolean square = false ;
30+
31+ protected final Paint borderPaint ;
32+ protected final Paint imagePaint ;
33+ protected BitmapShader shader ;
34+ protected Drawable drawable ;
35+ protected final Matrix matrix = new Matrix ();
36+
37+ public ShaderHelper () {
38+ borderPaint = new Paint ();
39+ borderPaint .setStyle (Paint .Style .STROKE );
40+ borderPaint .setAntiAlias (true );
41+
42+ imagePaint = new Paint ();
43+ imagePaint .setAntiAlias (true );
44+ }
45+
46+ public abstract void draw (Canvas canvas , Paint imagePaint , Paint borderPaint );
47+ public abstract void reset ();
48+ @ SuppressWarnings ("UnusedParameters" )
49+ public abstract void calculate (int bitmapWidth , int bitmapHeight , float width , float height , float scale , float translateX , float translateY );
50+
51+
52+ @ SuppressWarnings ("SameParameterValue" )
53+ protected final int dpToPx (DisplayMetrics displayMetrics , int dp ) {
54+ return Math .round (dp * (displayMetrics .xdpi / DisplayMetrics .DENSITY_DEFAULT ));
55+ }
56+
57+ public void init (Context context , AttributeSet attrs , int defStyle ) {
58+ if (attrs != null ){
59+ TypedArray typedArray = context .obtainStyledAttributes (attrs , R .styleable .ShaderImageView , defStyle , 0 );
60+ borderColor = typedArray .getColor (R .styleable .ShaderImageView_borderColor , borderColor );
61+ borderWidth = typedArray .getDimensionPixelSize (R .styleable .ShaderImageView_borderWidth , borderWidth );
62+ borderAlpha = typedArray .getFloat (R .styleable .ShaderImageView_borderAlpha , borderAlpha );
63+ square = typedArray .getBoolean (R .styleable .ShaderImageView_isSquare , square );
64+ typedArray .recycle ();
65+ }
66+
67+ borderPaint .setColor (borderColor );
68+ borderPaint .setAlpha (Float .valueOf (borderAlpha * ALPHA_MAX ).intValue ());
69+ borderPaint .setStrokeWidth (borderWidth );
70+ }
71+
72+ public boolean onDraw (Canvas canvas ) {
73+ if (shader == null ) {
74+ createShader ();
75+ }
76+ if (shader != null && viewWidth > 0 && viewHeight > 0 ) {
77+ draw (canvas , imagePaint , borderPaint );
78+ return true ;
79+ }
80+
81+ return false ;
82+ }
83+
84+ public void onSizeChanged (int width , int height ) {
85+ if (viewWidth == width && viewHeight == height ) return ;
86+ viewWidth = width ;
87+ viewHeight = height ;
88+ if (isSquare ()) {
89+ viewWidth = viewHeight = Math .min (width , height );
90+ }
91+ if (shader != null ) {
92+ calculateDrawableSizes ();
93+ }
94+ }
95+
96+ public Bitmap calculateDrawableSizes () {
97+ Bitmap bitmap = getBitmap ();
98+ if (bitmap != null ) {
99+ int bitmapWidth = bitmap .getWidth ();
100+ int bitmapHeight = bitmap .getHeight ();
101+
102+ if (bitmapWidth > 0 && bitmapHeight > 0 ) {
103+ float width = Math .round (viewWidth - 2f * borderWidth );
104+ float height = Math .round (viewHeight - 2f * borderWidth );
105+
106+ float scale ;
107+ float translateX = 0 ;
108+ float translateY = 0 ;
109+
110+ if (bitmapWidth * height > width * bitmapHeight ) {
111+ scale = height / bitmapHeight ;
112+ translateX = Math .round ((width /scale - bitmapWidth ) / 2f );
113+ } else {
114+ scale = width / (float ) bitmapWidth ;
115+ translateY = Math .round ((height /scale - bitmapHeight ) / 2f );
116+ }
117+
118+ matrix .setScale (scale , scale );
119+ matrix .preTranslate (translateX , translateY );
120+ matrix .postTranslate (borderWidth , borderWidth );
121+
122+ calculate (bitmapWidth , bitmapHeight , width , height , scale , translateX , translateY );
123+
124+ return bitmap ;
125+ }
126+ }
127+
128+ reset ();
129+ return null ;
130+ }
131+
132+ public final void onImageDrawableReset (Drawable drawable ) {
133+ this .drawable = drawable ;
134+ shader = null ;
135+ imagePaint .setShader (null );
136+ }
137+
138+ protected void createShader () {
139+ Bitmap bitmap = calculateDrawableSizes ();
140+ if (bitmap != null && bitmap .getWidth () > 0 && bitmap .getHeight () > 0 ) {
141+ shader = new BitmapShader (bitmap , Shader .TileMode .CLAMP , Shader .TileMode .CLAMP );
142+ imagePaint .setShader (shader );
143+ }
144+ }
145+
146+ protected Bitmap getBitmap () {
147+ Bitmap bitmap = null ;
148+ if (drawable != null ) {
149+ if (drawable instanceof BitmapDrawable ) {
150+ bitmap = ((BitmapDrawable ) drawable ).getBitmap ();
151+ }
152+ }
153+
154+ return bitmap ;
155+ }
156+
157+ public final int getBorderColor () {
158+ return borderColor ;
159+ }
160+
161+ public final void setBorderColor (final int borderColor ) {
162+ this .borderColor = borderColor ;
163+ if (borderPaint != null ) {
164+ borderPaint .setColor (borderColor );
165+ }
166+ }
167+
168+ public final int getBorderWidth () {
169+ return borderWidth ;
170+ }
171+
172+ public final void setBorderWidth (final int borderWidth ) {
173+ this .borderWidth = borderWidth ;
174+ if (borderPaint != null ) {
175+ borderPaint .setStrokeWidth (borderWidth );
176+ }
177+ }
178+
179+ public final float getBorderAlpha () {
180+ return borderAlpha ;
181+ }
182+
183+ public final void setBorderAlpha (final float borderAlpha ) {
184+ this .borderAlpha = borderAlpha ;
185+ if (borderPaint != null ) {
186+ borderPaint .setAlpha (Float .valueOf (borderAlpha * ALPHA_MAX ).intValue ());
187+ }
188+ }
189+
190+ public final void setSquare (final boolean square ) {
191+ this .square = square ;
192+ }
193+
194+ public final boolean isSquare () {
195+ return square ;
196+ }
197+ }
0 commit comments