android 图片自动移动位置信息,图片根据内容中心点移动位置 ImageView

最近遇到一个问题:

我们在显示一张图片时,需要的效果像:

0818b9ca8b590ca3270a3433284dd417.png

使用ImageView需要固定宽高比,但给定图片的宽高比是不一样的,怎么使内容在view 中,且图片不变形呢?这时候,单纯的使用ImageView的ScaleType属性不是让图片变形就是我们要显示的内容点被切除出去了。

android方面:我试过两种方法

一:在设置ImageView的图片前,先根据获取的BitMap重新切出一个新的bitmap

使用的方法是createBitmap(bitmap, x, y,bitmap.getWidth() - x, (int) (bitmap.getWidth() * 0.65526316d));x,y是计算出来要从该位置开始切出一个一个长宽比例为0.65526316d 的bitmap后放入ImageView 中。

这个方法目前只对长比宽大的情况下有效,当宽比长大时会出错。而且对内存也有影响。

代码如下:

//x1,y1是内容点在图片上的比例点

double x1 = 0.6;

double y1 = 0.7;

//拿到获得的bitmap的宽高

int imgw = bitmap.getWidth();

int imgh = bitmap.getHeight();

//计算内容点的坐标

int w = (int) (imgw * x1);

int h = (int) (imgh * y1);

//计算我们切出bitmap的起始点,如果内容点原本就在imageview

//的前半部分,我们就不需要在切出来了

int x = (show_img.getWidth() / 2 >= w) ? 0 : (w - show_img.getWidth() / 2);

int y = (show_img.getHeight() / 2 >= h) ? 0 : (h - show_img.getHeight() / 2);

//新建一个bitmap

Bitmap bi = Bitmap.createBitmap(bitmap, x, y, img1.getWidth() - x, (int) (img1.getWidth() * 0.65526316d));

show_img.setImageBitmap(bi);

二:使用ImageView 的setImageMatrix()方法,将图片按计算出来的数据平移,将内容移动到ImageView区域,这里必须要将ImageView的属性android:scaleType=”matrix”设置为matrix。

这里使用imageLoader三方库来加载图片,记得使用前初始化它

imageLoader的使用情趣看其他人的、、

//初始化imageLoader

imageLoader.init(ImageLoaderConfiguration.createDefault(ImgListviewActivity.this));

下面是关键代码:

//原图,我们常用的

imageLoader.displayImage(list.get(position), holder.img,getOptions());

//移动图,借用Listener能获取到它的bitmap

imageLoader.displayImage(list.get(position), holder.show_img, getOptions(), new SimpleImageLoadingListener() {

@Override

public void onLoadingComplete(String imageUri, View view, Bitmap bitmap) {

super.onLoadingComplete(imageUri, view, bitmap);

ImageView imgv = (ImageView) view;

Matrix matrix = new Matrix();

float bitmapWidth = bitmap.getWidth();

float bitmapHeight = bitmap.getHeight();

//内容中心点所在图片的比例坐标

float Face_center_x = 0.5f;

float Face_center_y = 0.5f;

//缩放比例、使图片填充满view

float Scale = (imgv.getHeight() / bitmapHeight >= imgv.getWidth() / bitmapWidth) ? imgv.getHeight() / bitmapHeight : imgv.getWidth() / bitmapWidth;

matrix.postScale(Scale, Scale);

//缩放后的图片宽高

float scaleBitmapWidth = Scale * bitmapWidth;

float scaleBitmapHeight = Scale * bitmapHeight;

if (scaleBitmapWidth > scaleBitmapHeight) { //宽度图

//移动的距离计算,下方有解释

float translate = (imgv.getWidth() / 2 >= Face_center_x * scaleBitmapWidth) ? 0 : ((Face_center_x * scaleBitmapWidth) - imgv.getWidth() / 2);

if (scaleBitmapWidth - translate <= imgv.getWidth()) {

translate = scaleBitmapWidth - imgv.getWidth();

}

matrix.postTranslate(-translate, 0);

} else { //高度图

float translate = (imgv.getHeight() / 2 >= Face_center_y * scaleBitmapHeight) ? 0 : ((Face_center_y * scaleBitmapHeight) - imgv.getHeight() / 2);

if (scaleBitmapHeight - translate <= imgv.getHeight()) {

translate = scaleBitmapHeight - imgv.getHeight();

}

matrix.postTranslate(0, -translate);

}

imgv.setImageMatrix(matrix);

imgv.setImageBitmap(bitmap);

}

});

计算移动距离的公式

float translate = (imgv.getWidth() / 2 >= Face_center_x * scaleBitmapWidth) ? 0

: ((Face_center_x * scaleBitmapWidth) - imgv.getWidth() / 2);

if (scaleBitmapWidth - translate <= imgv.getWidth()) {

translate = scaleBitmapWidth - imgv.getWidth();

}

这是宽度图的计算公式

imgv.getWidth() / 2 >= Face_center_x * scaleBitmapWidth 是判断内容中心点在左边多远,需不需要平移。如图

0818b9ca8b590ca3270a3433284dd417.png

下面是判断会不会移动过头,造成右边出现空白的情况

if (scaleBitmapWidth - translate <= imgv.getWidth()) {

translate = scaleBitmapWidth - imgv.getWidth();

}

0818b9ca8b590ca3270a3433284dd417.png

getOptions()是图片加载的一些情况

public DisplayImageOptions getOptions() {

DisplayImageOptions options = new DisplayImageOptions.Builder()

.showStubImage(R.drawable.ic_launcher) // 设置图片下载期间显示的图片

.showImageForEmptyUri(R.drawable.ic_launcher) // 设置图片Uri为空或是错误的时候显示的图片

.showImageOnFail(R.drawable.ic_launcher) // 设置图片加载过程中发生错误显示的图片

.cacheInMemory(true) // 设置下载的图片是否缓存在内存中

.cacheOnDisc(true) // 设置下载的图片是否缓存在SD卡中

.build(); // 创建配置过得DisplayImageOption对象

return options;

}

设置View的宽高方法:

private int width = 0;

private int height = 0;

private void scaleImage(ImageView view) {

//获取屏幕的宽高

WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);

DisplayMetrics outMetrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(outMetrics);

if (width == 0) {

width = outMetrics.widthPixels;

}

if (height == 0) {

height = (int) (width * 0.65526316d);

}

LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();

if (params == null) {

params = new LinearLayout.LayoutParams(width, height);

} else {

params.height = height;

params.width = width;

}

view.setLayoutParams(params);

}

这个方法每个图片加载都会走三遍,我也不清楚情况、、、

谢谢指教!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值