在项目中有很多地方需要展示图片,我们怎才能不失真的展示呢,如果图片宽大于屏幕,我们跟据宽的比例把图片缩放,高也同理.
工具类代码如下:
//根据图片路径把图片不失真展示
public static Bitmap displayFromFile(ImageInfo info) {
Bitmap bm = null;
InputStream is = null;
try {
is = new FileInputStream(info.path);
bm = displayFromStream(is, info);
int degree = getExifOrientation(info.path);
if (info.isLandscape()) {
degree += 90;
}
if (degree % 360 != 0) {
bm = rotate(bm, degree);
}
if (info.scale) {
bm = scale(bm, info.isLandscape() ? info.height : info.width,
info.isLandscape() ? info.width : info.height);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return bm;
}
//资源文件中的图片不失真展示
public static Bitmap displayFromDrawable(Context context, ImageInfo info) {
Bitmap bm = null;
InputStream is = null;
try {
is = context.getResources().openRawResource(info.resId);
bm = displayFromStream(is, info);
if (info.scale) {
bm = scale(bm, info.isLandscape() ? info.height : info.width,
info.isLandscape() ? info.width : info.height);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return bm;
}
//旋转图片
private static Bitmap rotate(Bitmap bm, int degree) {
if (bm == null) {
return bm;
}
Matrix m = new Matrix();
m.setRotate(degree, (float) bm.getWidth() / 2,
(float) bm.getHeight() / 2);
float targetX, targetY;
if (degree == 90) {
targetX = bm.getHeight();
targetY = 0;
} else {
targetX = bm.getHeight();
targetY = bm.getWidth();
}
final float[] values = new float[9];
m.getValues(values);
float x1 = values[Matrix.MTRANS_X];
float y1 = values[Matrix.MTRANS_Y];
m.postTranslate(targetX - x1, targetY - y1);
Bitmap bm1 = Bitmap.createBitmap(bm.getHeight(), bm.getWidth(),
Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
Canvas canvas = new Canvas(bm1);
canvas.drawBitmap(bm, m, paint);
if (bm != null && bm != bm1) {
bm.recycle();
bm = null;
}
return bm1;
}
//判断图片的横竖
public static int getExifOrientation(String filepath) {
int degree = 0;
try {
ExifInterface exif = new ExifInterface(filepath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, -1);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return degree;
}
//对处理图片使图片适应屏幕
private static Bitmap scale(Bitmap bm, float width, float height) {
if (bm == null || width == 0 || height == 0) {
return bm;
}
Matrix m = new Matrix();
float scale = Math.max(width / bm.getWidth(), height / bm.getHeight());
m.postScale(scale, scale);
Bitmap temp1 = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), m, false);
if (bm != null && bm != temp1) {
bm.recycle();
bm = null;
}
int x = Math.max(0, (int) ((temp1.getWidth() - width) / 2));
int y = Math.max(0, (int) ((temp1.getHeight() - height) / 2));
Bitmap temp2 = Bitmap.createBitmap(temp1, x, y, (int) width,
(int) height, null, false);
if (temp1 != null && temp1 != temp2) {
temp1.recycle();
temp1 = null;
}
return temp2;
}
//图片进行压缩
private static Bitmap displayFromStream(InputStream is, ImageInfo info) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferredConfig = Bitmap.Config.RGB_565;
opts.inPurgeable = true;
opts.inInputShareable = true;
if (info.limitSize && info.width != 0 && info.height != 0) {
opts.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, opts);
int heightRatio = (int) Math.ceil(opts.outHeight
/ (float) info.height);
int widthRatio = (int) Math
.ceil(opts.outWidth / (float) info.width);
if (heightRatio > 1 && widthRatio > 1) {
opts.inSampleSize = heightRatio > widthRatio ? heightRatio
: widthRatio;
}
opts.inJustDecodeBounds = false;
}
return BitmapFactory.decodeStream(is, null, opts);
}
info主要用来获得图的属性 类代码如下:
public class ImageInfo {
// 图片来源 content, drawable, file, assets
public String scheme;
public String path;
public int resId;
public int width;
public int height;
public boolean limitSize = false;
public boolean scale;
private int orientation = Configuration.ORIENTATION_PORTRAIT;
public ImageInfo(String scheme) {
super();
this.scheme = scheme;
}
public ImageInfo(ImageInfo info) {
this.scheme = info.scheme;
this.path = info.path;
this.resId = info.resId;
this.width = info.width;
this.height = info.height;
this.limitSize = info.limitSize;
this.scale = info.scale;
this.orientation = info.orientation;
}
public void setOrientation(int orientation) {
if (this.orientation != orientation) {
int temp = width;
width = height;
height = temp;
this.orientation = orientation;
}
}
public int getOrientation() {
return orientation;
}
public boolean isLandscape() {
return orientation == Configuration.ORIENTATION_LANDSCAPE;
}
@Override
public String toString() {
return scheme + "-" + path + "-" + resId + "-" + width + "-" + height
+ "-" + limitSize + "-" + scale + "-" + orientation;
}
public static ImageInfo getMusicInfo(int albumId, boolean limitSize) {
ImageInfo info = new ImageInfo("music");
info.resId = albumId;
if (limitSize) {
info.limitSize = true;
info.width = 100;
info.height = 100;
}
return info;
}
public static ImageInfo getAssetsInfo(String path) {
ImageInfo info = new ImageInfo("assets");
info.path = path;
return info;
}
//资源文件中的图片
public static ImageInfo getDrawableInfo(int resId) {
ImageInfo info = new ImageInfo("drawable");
info.resId = resId;
return info;
}
//从相册中获取的图片
public static ImageInfo getFileInfo(String path) {
ImageInfo info = new ImageInfo("file");
info.path = path;
return info;
}
// public static ImageInfo getMusicInfo(String path, boolean limitSize) {
// ImageInfo info = new ImageInfo("music");
// info.path = path;
// if (limitSize) {
// info.limitSize = true;
// info.width = 100;
// info.height = 100;
// }
// return info;
// }
}
具体使用如下:
//先通过ImageInfo类中的getDrawableInfo方法把资源文件的路径设置进去
ImageInfo info = ImageInfo.getDrawableInfo(ps
.getChangeWallpaper());
//要展示图片区域的宽 ScreenUtil.getWindowsW(context)是屏幕的宽
info.width = ScreenUtil.getWindowsW(context);
//要展示图片区域的高 ScreenUtil.getWindowsH(context)是屏幕的高
info.height = ScreenUtil.getWindowsH(context);
//是竖着展示
info.scale = true;
//然后调用FileUtil.displayFromDrawable方法将图片展示
viewPager.setBackgroundDrawable(new BitmapDrawable(
getResources(), FileUtil.displayFromDrawable(
getContext(), info)));
//从相册中获取图片展示
ImageInfo info = ImageInfo.getFileInfo(ps.getSetWallpaper());
info.width = ScreenUtil.getWindowsW(context);
info.height = ScreenUtil.getWindowsH(context);
info.scale = true;
viewPager.setBackgroundDrawable(new BitmapDrawable(
getResources(), FileUtil.displayFromFile(info)));