Skip to content

Instantly share code, notes, and snippets.

@sromku
Created November 20, 2015 15:32
Show Gist options
  • Save sromku/73254681b933406b701b to your computer and use it in GitHub Desktop.
Save sromku/73254681b933406b701b to your computer and use it in GitHub Desktop.
Image View Top Crop / Bottom Crop
<resources>
<declare-styleable name="ImageScaleView">
<attr name="matrixType" format="enum">
<enum name="top_center" value="0" />
<enum name="bottom_center" value="1" />
</attr>
</declare-styleable>
</resources>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.sromku.views.ImageScaleView
android:layout_width="200dp"
android:layout_height="130dp"
android:scaleType="matrix"
app:matrixType="top_center"
android:src="@drawable/bg_big"/>
</LinearLayout>
/**
* Scale to center top or scale to center bottom
*
* @author sromku
*/
public class ImageScaleView extends ImageView {
private MatrixCropType mMatrixType = MatrixCropType.TOP_CENTER; // default
private enum MatrixCropType {
TOP_CENTER(0),
BOTTOM_CENTER(1);
private int mValue;
private MatrixCropType(int value) {
mValue = value;
}
public static MatrixCropType fromValue(int value) {
for (MatrixCropType matrixCropType : values()) {
if (matrixCropType.mValue == value) {
return matrixCropType;
}
}
// default
return MatrixCropType.TOP_CENTER;
}
}
public ImageScaleView(Context context) {
this(context, null);
}
public ImageScaleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ImageScaleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// get attributes
if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ImageScaleView, 0, 0);
try {
mMatrixType = MatrixCropType.fromValue(a.getInteger(R.styleable.ImageScaleView_matrixType, 0));
}
finally {
a.recycle();
}
}
}
@Override
protected boolean setFrame(int frameLeft, int frameTop, int frameRight, int frameBottom) {
Drawable drawable = getDrawable();
if (drawable != null) {
float frameWidth = frameRight - frameLeft;
float frameHeight = frameBottom - frameTop;
float originalImageWidth = (float) getDrawable().getIntrinsicWidth();
float originalImageHeight = (float) getDrawable().getIntrinsicHeight();
float usedScaleFactor = 1;
if ((frameWidth > originalImageWidth) || (frameHeight > originalImageHeight)) {
// If frame is bigger than image
// => Crop it, keep aspect ratio and position it at the bottom
// and
// center horizontally
float fitHorizontallyScaleFactor = frameWidth / originalImageWidth;
float fitVerticallyScaleFactor = frameHeight / originalImageHeight;
usedScaleFactor = Math.max(fitHorizontallyScaleFactor, fitVerticallyScaleFactor);
}
float newImageWidth = originalImageWidth * usedScaleFactor;
float newImageHeight = originalImageHeight * usedScaleFactor;
Matrix matrix = getImageMatrix();
matrix.setScale(usedScaleFactor, usedScaleFactor, 0, 0);
switch (mMatrixType) {
case TOP_CENTER:
matrix.postTranslate((frameWidth - newImageWidth) / 2, 0);
break;
case BOTTOM_CENTER:
matrix.postTranslate((frameWidth - newImageWidth) / 2, frameHeight - newImageHeight);
break;
default:
break;
}
setImageMatrix(matrix);
}
return super.setFrame(frameLeft, frameTop, frameRight, frameBottom);
}
}
@mj-manna
Copy link

great

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment