Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
CropImageView
=============
[![Hex.pm](https://img.shields.io/hexpm/l/plug.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![Platform](https://img.shields.io/badge/platform-android-green.svg)](http://developer.android.com/index.html)


An ImageView that supports different kind of cropping rather than the only Android is currently supporting: `centerCrop`

Expand Down
2 changes: 1 addition & 1 deletion cropimageview-samples/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ buildscript {
}

dependencies {
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.0'
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -32,6 +34,7 @@
public class CropImageView extends ImageView {

private CropType cropType = CropType.NONE;
private float cornerRadius = -1;

public CropImageView(Context context) {
super(context);
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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:
Expand All @@ -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:
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
1 change: 1 addition & 0 deletions cropimageview/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<enum name="centerTop" value="6"/>
<enum name="centerBottom" value="7"/>
</attr>
<attr name="cornerRadius" format="dimension"/>
</declare-styleable>

</resources>