diff --git a/README.md b/README.md
index 4be3c0a..8a5094a 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
CropImageView
=============
+[](http://www.apache.org/licenses/LICENSE-2.0) [](http://developer.android.com/index.html)
+
An ImageView that supports different kind of cropping rather than the only Android is currently supporting: `centerCrop`
diff --git a/cropimageview-samples/build.gradle b/cropimageview-samples/build.gradle
index 4a907c4..c19ad5e 100644
--- a/cropimageview-samples/build.gradle
+++ b/cropimageview-samples/build.gradle
@@ -7,7 +7,7 @@ buildscript {
}
dependencies {
- classpath 'com.jakewharton.hugo:hugo-plugin:1.2.0'
+ classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
}
}
diff --git a/cropimageview/src/main/java/com/cesards/cropimageview/CropImageView.java b/cropimageview/src/main/java/com/cesards/cropimageview/CropImageView.java
index c0a1cab..7828d0c 100644
--- a/cropimageview/src/main/java/com/cesards/cropimageview/CropImageView.java
+++ b/cropimageview/src/main/java/com/cesards/cropimageview/CropImageView.java
@@ -20,9 +20,11 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Matrix;
+import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.ImageView;
+
import java.util.HashMap;
import java.util.Map;
@@ -32,6 +34,7 @@
public class CropImageView extends ImageView {
private CropType cropType = CropType.NONE;
+ private float cornerRadius = -1;
public CropImageView(Context context) {
super(context);
@@ -47,8 +50,9 @@ public CropImageView(Context context, AttributeSet attrs, int defStyle) {
this.parseAttributes(attrs);
}
- @TargetApi(Build.VERSION_CODES.LOLLIPOP) public CropImageView(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public CropImageView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
this.parseAttributes(attrs);
}
@@ -90,28 +94,58 @@ private void parseAttributes(AttributeSet attrs) {
setScaleType(ScaleType.MATRIX);
this.cropType = CropType.get(crop);
}
+
+ cornerRadius = a.getDimensionPixelSize(R.styleable.CropImageView_cornerRadius, -1);
a.recycle();
}
+ //needs to be set before drawable
+ public void setCornerRadius(float cornerRadius){
+ this.cornerRadius = cornerRadius;
+ }
+
+ public float getCornerRadius() {
+ return cornerRadius;
+ }
+
@Override
protected boolean setFrame(int l, int t, int r, int b) {
final boolean changed = super.setFrame(l, t, r, b);
if (!isInEditMode()) {
this.computeImageMatrix();
}
+
return changed;
}
+ @Override
+ public void setImageDrawable(Drawable drawable) {
+
+ if (cornerRadius > 0) {
+ drawable = RoundedCornerDrawable.fromDrawable(drawable);
+ ((RoundedCornerDrawable) drawable).setCornerRadius(cornerRadius);
+ }
+
+ super.setImageDrawable(drawable);
+ }
+
private void computeImageMatrix() {
final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
if (cropType != CropType.NONE && viewHeight > 0 && viewWidth > 0) {
- final Matrix matrix = getImageMatrix();
-
- int drawableWidth = getDrawable().getIntrinsicWidth();
- int drawableHeight = getDrawable().getIntrinsicHeight();
+ Matrix matrix = getImageMatrix();
+
+ int drawableWidth;
+ int drawableHeight;
+ if (cornerRadius > 0 && getDrawable() instanceof RoundedCornerDrawable) {
+ drawableWidth = ((RoundedCornerDrawable) getDrawable()).getBitmapWidth();
+ drawableHeight = ((RoundedCornerDrawable) getDrawable()).getBitmapHeight();
+ } else {
+ drawableWidth = getDrawable().getIntrinsicWidth();
+ drawableHeight = getDrawable().getIntrinsicHeight();
+ }
final float scaleY = (float) viewHeight / (float) drawableHeight;
final float scaleX = (float) viewWidth / (float) drawableWidth;
@@ -122,16 +156,22 @@ private void computeImageMatrix() {
final float postDrawableWidth = drawableWidth * scale;
final float xTranslation = getXTranslation(cropType, viewWidth, postDrawableWidth, verticalImageMode);
- final float postDrawabeHeigth = drawableHeight * scale;
- final float yTranslation = getYTranslation(cropType, viewHeight, postDrawabeHeigth, verticalImageMode);
+ final float postDrawableHeight = drawableHeight * scale;
+ final float yTranslation = getYTranslation(cropType, viewHeight, postDrawableHeight, verticalImageMode);
matrix.postTranslate(xTranslation, yTranslation);
- setImageMatrix(matrix);
+
+ if (cornerRadius > 0 && getDrawable() instanceof RoundedCornerDrawable) {
+ ((RoundedCornerDrawable) getDrawable()).setMatrix(matrix);
+ setImageMatrix(null);
+ } else {
+ setImageMatrix(matrix);
+ }
}
}
- private float getYTranslation(CropType cropType, int viewHeight, float postDrawabeHeigth,
- boolean verticalImageMode) {
+ public static float getYTranslation(CropType cropType, int viewHeight, float postDrawabeHeigth,
+ boolean verticalImageMode) {
if (verticalImageMode) {
switch (cropType) {
case CENTER_BOTTOM:
@@ -149,8 +189,8 @@ private float getYTranslation(CropType cropType, int viewHeight, float postDrawa
return 0;
}
- private float getXTranslation(CropType cropType, int viewWidth, float postDrawableWidth,
- boolean verticalImageMode) {
+ public static float getXTranslation(CropType cropType, int viewWidth, float postDrawableWidth,
+ boolean verticalImageMode) {
if (!verticalImageMode) {
switch (cropType) {
case RIGHT_TOP:
diff --git a/cropimageview/src/main/java/com/cesards/cropimageview/RoundedCornerDrawable.java b/cropimageview/src/main/java/com/cesards/cropimageview/RoundedCornerDrawable.java
new file mode 100644
index 0000000..e664c61
--- /dev/null
+++ b/cropimageview/src/main/java/com/cesards/cropimageview/RoundedCornerDrawable.java
@@ -0,0 +1,131 @@
+package com.cesards.cropimageview;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * Created by victorcassone on 5/23/15.
+ */
+public class RoundedCornerDrawable extends Drawable {
+
+ private RectF mDrawableRect = new RectF();
+ private Bitmap mBitmap;
+ private Paint mBitmapPaint;
+ private float mCornerRadius;
+ private BitmapShader mShader;
+
+ public RoundedCornerDrawable(Bitmap bitmap) {
+ mBitmap = bitmap;
+
+ mBitmapPaint = new Paint();
+ mBitmapPaint.setStyle(Paint.Style.FILL);
+ mBitmapPaint.setAntiAlias(true);
+
+ mShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+ }
+
+ public void setCornerRadius(float radius) {
+ mCornerRadius = radius;
+ }
+
+ @Override
+ protected void onBoundsChange(Rect bounds) {
+ super.onBoundsChange(bounds);
+ mDrawableRect.set(bounds);
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ mBitmapPaint.setShader(mShader);
+ canvas.drawRoundRect(mDrawableRect, mCornerRadius, mCornerRadius, mBitmapPaint);
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ mBitmapPaint.setAlpha(alpha);
+ invalidateSelf();
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ mBitmapPaint.setColorFilter(cf);
+ invalidateSelf();
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ public void setMatrix(Matrix matrix){
+ mShader.setLocalMatrix(matrix);
+ invalidateSelf();
+ }
+
+ public int getBitmapWidth(){
+ return mBitmap.getWidth();
+ }
+
+ public int getBitmapHeight(){
+ return mBitmap.getHeight();
+ }
+
+ public static Drawable fromDrawable(Drawable drawable) {
+ if (drawable != null) {
+ if (drawable instanceof RoundedCornerDrawable) {
+ return drawable;
+ } else if (drawable instanceof LayerDrawable) {
+ LayerDrawable ld = (LayerDrawable) drawable;
+ int num = ld.getNumberOfLayers();
+
+ for (int i = 0; i < num; i++) {
+ Drawable d = ld.getDrawable(i);
+ ld.setDrawableByLayerId(ld.getId(i), fromDrawable(d));
+ }
+ return ld;
+ }
+
+ Bitmap bm = drawableToBitmap(drawable);
+ if (bm != null) {
+ return new RoundedCornerDrawable(bm);
+ }
+ }
+ return drawable;
+ }
+
+ public static Bitmap drawableToBitmap(Drawable drawable) {
+ if (drawable instanceof BitmapDrawable) {
+ return ((BitmapDrawable) drawable).getBitmap();
+ }
+
+ Bitmap bitmap;
+ int width = Math.max(drawable.getIntrinsicWidth(), 2);
+ int height = Math.max(drawable.getIntrinsicHeight(), 2);
+ try {
+ bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ } catch (Exception e) {
+ e.printStackTrace();
+ bitmap = null;
+ }
+
+ return bitmap;
+ }
+}
\ No newline at end of file
diff --git a/cropimageview/src/main/res/values/attrs.xml b/cropimageview/src/main/res/values/attrs.xml
index bcdaad2..a1eb4d7 100644
--- a/cropimageview/src/main/res/values/attrs.xml
+++ b/cropimageview/src/main/res/values/attrs.xml
@@ -12,6 +12,7 @@
+
\ No newline at end of file