Skip to content

Instantly share code, notes, and snippets.

@VladSumtsov
Last active September 17, 2015 08:06
Show Gist options
  • Save VladSumtsov/03b57e9e52256080d9f1 to your computer and use it in GitHub Desktop.
Save VladSumtsov/03b57e9e52256080d9f1 to your computer and use it in GitHub Desktop.
Center image in the ImageView using matrix scheme.
package com.aliens.ui.widget;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.PictureDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class CenterImageView extends ImageView {
public CenterImageView(Context context) {
super(context);
}
public CenterImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CenterImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setCenterImage(PictureDrawable drawable) {
centerPaddings(drawable, new float[]{0, 0, 0, 0});
super.setImageDrawable(drawable);
}
/**
* @param paddingCoef left/top/right/bottom coefficient paddings.
* Ex.: left should be calculated as (Left transparent padding)/(Image width)
*/
public void setCenterImage(PictureDrawable drawable, float[] paddingCoef) {
centerPaddings(drawable, paddingCoef);
super.setImageDrawable(drawable);
}
private void centerPaddings(PictureDrawable picture, float[] paddings) {
setScaleType(ScaleType.MATRIX);
int pictureWidth = picture.getIntrinsicWidth();
int pictureHeight = picture.getIntrinsicHeight();
int left = (int) (paddings[0] * pictureWidth);
int right = (int) (paddings[2] * pictureWidth);
int top = (int) (paddings[1] * pictureHeight);
int bottom = (int) (paddings[3] * pictureHeight);
int imageWidth = pictureWidth - left - right;
int imageHeight = pictureHeight - top - bottom;
float scaleIncrease = Math.min(pictureHeight / (float) imageHeight, pictureWidth / (float) imageWidth);
float sx = getWidth() / (float) pictureWidth * scaleIncrease;
float sy = getHeight() / (float) pictureHeight * scaleIncrease;
float leftPad = (right + left - (pictureWidth - pictureWidth / scaleIncrease)) / 2 - left;
float topPad = (bottom + top - (pictureHeight - pictureHeight / scaleIncrease)) / 2 - top;
Matrix matrix = new Matrix();
matrix.postScale(sx, sy);
matrix.postTranslate(leftPad * sx, topPad * sy);
setImageMatrix(matrix);
}
}
//Try to cache calculated paddings. Method isn't fast.
private float[] calculateAndSavePaddings(int id, SVG svg) {
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(bitmap);
svg.renderToCanvas(canvas);
int[] pixels = new int[bitmap.getHeight() * bitmap.getWidth()];
int top = 0, bottom = 0, left = 0, right = 0, i;
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
for (i = 0; i < pixels.length; i++) {
if (pixels[i] != 0) {
top = i / bitmap.getWidth();
break;
}
}
outerLoop1:
for (i = 0; i < bitmap.getWidth(); i++) {
for (int j = i; j < pixels.length; j += bitmap.getWidth()) {
if (pixels[j] != 0) {
left = j % bitmap.getWidth();
break outerLoop1;
}
}
}
for (i = pixels.length - 1; i >= 0; i--) {
if (pixels[i] != 0) {
bottom = (pixels.length - i) / bitmap.getWidth();
break;
}
}
outerLoop2:
for (i = pixels.length - 1; i >= 0; i--) {
for (int j = i; j >= 0; j -= bitmap.getWidth()) {
if (pixels[j] != 0) {
right = bitmap.getWidth() - (j % bitmap.getWidth());
break outerLoop2;
}
}
}
bitmap.recycle();
return new float[]{left,top,right,bottom};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment