不失真的图片展示

原创 2015年07月09日 13:59:28

在项目中有很多地方需要展示图片,我们怎才能不失真的展示呢,如果图片宽大于屏幕,我们跟据宽的比例把图片缩放,高也同理.

工具类代码如下:

//根据图片路径把图片不失真展示
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)));


Android高效压缩图片不失真的方法总结

前言 之前有个项目我负责聊天模块,做到图片消息那一块时,因为需要先上传到服务器然后取得返回的图片网络地址,考虑到无论是从相机拍摄还是从相册上传的图片,都有可能由于过大从而导致发送消息耗时过长以及损耗用...
  • Alfred_C
  • Alfred_C
  • 2016年01月19日 15:37
  • 7055

ImageView的几种对图片的缩放处理 解决imageview放大图片后失真问题解决办法

我的解决办法: 1 首先设置android:layout_width=”wrap_content”和android:layout_height=”wrap_content”,否则你按比例缩放后的...
  • tiramisu_ljh
  • tiramisu_ljh
  • 2017年04月01日 13:57
  • 2252

Android压缩图片到100K以下并保持不失真的高效方法

在开发Android企业应用时,会经常上传图片到服务器,而我们公司目前维护的一个项目便是如此。该项目是通过私有apn与服务器进行交互的,联通的还好,但移动的速度实在太慢,客户在使用软件的过程中,由于上...
  • qq_35114086
  • qq_35114086
  • 2016年09月22日 17:32
  • 1182

【Android】0行代码实现任意形状图片展示--android-anyshape

前言在Android开发中, 我们经常会遇到一些场景, 需要以一些特殊的形状显示图片, 比如圆角矩形、圆形等等。关于如何绘制这类形状, 网上已经有很多的方案,比如自定义控件重写onDraw方法, 通过...
  • u013015161
  • u013015161
  • 2016年03月27日 20:28
  • 3299

html+css实现3D旋转图片展示

MyHtml.html --> *{margin:0px ; padding:0px} body{background:url("imgs/bg.jp...
  • u012651389
  • u012651389
  • 2015年02月25日 17:12
  • 1368

jQuery Lightbox(balupton版)图片展示插件使用

一、信息 原作者:Benjamin Arthur Lupton 当前版本:v1.3.7最终版 发布日期:2009年4月25日 项目地址:http://jquery.com/plugins/pr...
  • Truong
  • Truong
  • 2014年03月28日 21:38
  • 1000

android-自定义View-GridListView(仿Q空间好友动态列表图片展示方式)

先来看下实现的效果图:
  • lhlhlh111000
  • lhlhlh111000
  • 2014年09月25日 08:51
  • 1999

Android超长图片展示

安卓中图片一般有两种加载方式: ImageView和图片框架。普通的固定资源图片用ImageView就行;网络图片或者列表中的图片,UIL、Fresco、Picasso等框架也能解决下载、缓存管理、滑...
  • rome753
  • rome753
  • 2017年03月24日 00:56
  • 295

Winform客户端到Java服务端的图片展示和上传

图片上传在JavaWeb方面已经有成熟的组件,那么对应到Winform(C#编写的富客户端组件)客户端到Java服务端的图片展示和上传,其实也有一套为之可行的方案...
  • qing_gee
  • qing_gee
  • 2015年12月29日 11:37
  • 2267

十个技术含量超高的JS图片展示特效

十款超级酷的JS图片展示代码,一定会给你强烈的震撼,技术含量超高,保证你没见过 1.预览地址: http://preview.zcool.com.cn/code/js/04/1/ 2.预...
  • fupozsl
  • fupozsl
  • 2012年04月05日 20:59
  • 1327
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:不失真的图片展示
举报原因:
原因补充:

(最多只允许输入30个字)