Можно ли изменить поведение ImageView, чтобы при scaleType="centerCrop", задать "фейковые" координаты центра?
Нужно передать фото пользователя и выровнять фото относительно лица, лишнее обрезать.
Может быть есть библиотека, которая поможет мне это сделать. Или какой-то прием.
Подобное реализовано в ВК, там при загрузке фото передаются координаты, относительно которых нужно выравнивать фото в профиле пользователя.
---------------------------------------------------------------------------------------------------------------------------------
Вопрос решен наследованием от ImgeView. Если у кого-то будет такая же проблема, решение ниже:
public class CropImageView extends ImageView
{
private int centerX;
private int centerY;
public CropImageView(Context context)
{
super(context);
}
public CropImageView(Context ctx, AttributeSet attrs)
{
super(ctx, attrs);
TypedArray a = ctx.getTheme().obtainStyledAttributes( attrs, R.styleable.CropImageView, 0, 0);
try
{
centerX = a.getInteger(R.styleable.CropImageView_centrX, 0);
centerY = a.getInteger(R.styleable.CropImageView_centrY, 0);
} finally
{
a.recycle();
}
}
public CropImageView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) return;
if (getWidth() == 0 || getHeight() == 0) return;
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
Bitmap croppedBitmap = getCroppedBitmap(bitmap);
canvas.drawBitmap(croppedBitmap, 0, 0, null);
}
private Bitmap getCroppedBitmap(Bitmap bitmap)
{
Bitmap finalBitmap;
int width = this.getWidth();
int height = this.getHeight();
float coefficient = width / height;
int finalWidth;
int finalHeight;
if (bitmap.getWidth() / bitmap.getHeight() > coefficient) //Если нужно отрезать слева/права
{
//Считаем новую ширину
int newWidth = Math.round(bitmap.getHeight() * coefficient);
//Считаем точку по иксу с которой обрезать
int cropX = centerX - (newWidth / 2);
if (cropX < 0) cropX = 0;
int cropY = 0;
finalBitmap = Bitmap.createBitmap(bitmap, cropX, cropY, newWidth, bitmap.getHeight());
}
else if (bitmap.getWidth() / bitmap.getHeight() < coefficient) //Если нужно отрезать сверху/снизу
{
//Считаем новую высоту
int newHeight = Math.round(bitmap.getWidth() / coefficient);
//Считаем точку по иксу с которой обрезать
int cropX = 0;
int cropY = centerY - (newHeight / 2);
if (cropY < 0) cropY = 0;
finalBitmap = Bitmap.createBitmap(bitmap, cropX, cropY, bitmap.getWidth(), newHeight);
}
else //Если вдруг пропорции соблюденены
{
finalBitmap = bitmap;
}
return finalBitmap;
}
public int getCenterX()
{
return centerX;
}
public void setCenterX(int centerX)
{
this.centerX = centerX;
}
public int getCenterY()
{
return centerY;
}
public void setCenterY(int centerY)
{
this.centerY = centerY;
}
}
В res/values/attr.xml
<resources>
<declare-styleable name="CropImageView">
<attr name="centrX" format="integer"/>
<attr name="centrY" format="integer"/>
</declare-styleable>
</resources>
В layouts:
<com.base.base.components.CropImageView
app:centrX="400"
app:centrY="540"
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="@+id/imageView6"
android:src="@drawable/ann_picbig"
android:scaleType="centerCrop"/>