Android CacheImage之下载获取指定大小图片

本文介绍了一个用于处理图片的工具类,包括将图片调整为指定尺寸的功能,并提供了从网络下载特定大小图片的方法。此外,还实现了文件流复制及检查是否处于主线程的功能。
public final class ImageUtils {
	private static final String TAG = "ImageUtils";
	private static final boolean DEBUG = false;
	/**
	 * 图片工具类
	 */
	
	private ImageUtils() {
	}
	
	
	/**
	 * 把图片转换成指定的大小,规则如下:
	 *       当前图片的宽度和高度是否都大于指定高度的二倍,
	 *       是则缩小2倍,继续判断大小
	 * @param f
	 * @param width
	 * @param height
	 * @return
	 * @throws IOException 
	 */
	public static Bitmap decode2file(File f,final int width,final int height) throws IOException {
		if(f == null){
			if(DEBUG)
				Log.i(TAG, "file is null in decode");
			return null;
		}
		if (!f.exists()) {
			throw new IOException("local file does not exist: " + f);
		}
		if (!f.canRead()) {
			throw new IOException("cannot read from local file: " + f);
		}
		if(DEBUG)
			Log.i(TAG, ">>>>>>>>>>>>>>decode start file name : " + f.getName() + ">> width : " + width + ">>height : " + height);
		try {
			// 加载图片,获取大小
			BitmapFactory.Options oc = new BitmapFactory.Options();
			// 设置成 true,只获取图片大小,不会把图片加载到内存中
			oc.inJustDecodeBounds = true;
			FileInputStream fisc = new FileInputStream(f);
			BitmapFactory.decodeStream(fisc, null, oc);
			fisc.close();
			fisc = null;
			
			//计算
			int tempw = oc.outWidth, temph = oc.outHeight;
			int scale = 1;
			while(true){
				if(tempw / 2 < width || temph < height)
					break;
				tempw /= 2;
				temph /= 2;
				scale *= 2;
			}
			//加载指定规格图片
			BitmapFactory.Options oi = new BitmapFactory.Options();
			oi.inSampleSize = scale;
			FileInputStream fisi = new FileInputStream(f);
			Bitmap b = BitmapFactory.decodeStream(fisi, null, oi);
			fisi.close();
			fisi = null;
			if(DEBUG)
				Log.i(TAG, "<<<<<<<<<<<<<<<<<< decode end");
			return b;
			
		} catch (FileNotFoundException e) {
			if(DEBUG)
				Log.e(TAG, "<<<<<<<<<<<<<<not find decode file");
		} catch (IOException e) {
			if(DEBUG)
				Log.e(TAG, "<<<<<<<<<<<<<io exception in decode");
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 下载指定大小的图片
	 * @param url
	 * @param width
	 * @param height
	 * @return
	 */
	public static  Bitmap getBitmapFromNet(String url,final int width,final int height){
		if(url == null){
			if (DEBUG)
				Log.i(TAG, ">>>>>>>>>>>>download image url is null");
			return null;
		}
		checkNotOnMainThead();
		if(DEBUG)
			Log.i(TAG, ">>>>>>>>>>>download image start url: " + url);
		
		Bitmap b = null;
		File tempFile = null;
		InputStream is = null;
		FileOutputStream fos = null;
		HttpURLConnection conn = null;
		try{
			URL imageURL = new URL(url);
			conn = (HttpURLConnection) imageURL.openConnection();
			//连接时间,等待读取时间和重定向
			conn.setConnectTimeout(20000);
			conn.setReadTimeout(20000);
			conn.setInstanceFollowRedirects(true);
			is = conn.getInputStream();
			tempFile = new File("temp_" + MD5.encode(url));
			fos = new FileOutputStream(tempFile);
			copyStream(is, fos);
			b = decode2file(tempFile, width, height);
			
			return b;
		}catch(Throwable tx){
			if(DEBUG)
				Log.e(TAG, "<<<<<<<<download exception");
			tx.printStackTrace();
			//发生内存溢出,清理缓存
			if(tx instanceof OutOfMemoryError){
				if(DEBUG)
					Log.e(TAG, "<<<<<<<<<<<download out of memory");
			}
			
		}finally{
			try {
				if (fos != null)
					fos.close();
				if(is != null)
					is.close();
				conn.disconnect();
				tempFile.delete();
			} catch (IOException e) {
				e.printStackTrace();
 
			}
		}
		return null;
	}
	
	/**
	 * 
	 * @param is
	 * @param os
	 * @throws IOException
	 */
	public static void copyStream(InputStream is , OutputStream os) throws IOException{
		final int buffSize = 1024;
		int count = 0;
		byte[] b = new byte[2 * buffSize];
		while(-1 != (count = is.read(b))){
			os.write(b, 0, count);
		}
	}
		/**
	 * 检查是否在主线程
	 */
	public static void checkNotOnMainThead(){
		if(Looper.myLooper() == Looper.getMainLooper()){
			throw new IllegalStateException("This method should not be called from the main/UI thread.");
		}
	}
	
	/**
	 * 
	 * @param b
	 * @param f
	 * @throws IOException
	 */
	public static void writeBitmap2File(Bitmap b, File f) throws IOException{
		if(b == null || f == null){
			if(DEBUG)
				Log.e(TAG, "bitmap or file is null bitmap: " + b + ">>>>>file: "  + f);
			return ;
		}
		if (!f.exists()) {
			throw new IOException("local file does not exist: " + f);
		}
		FileOutputStream fos = null;
		try{
			fos = new FileOutputStream(f);
			b.compress(CompressFormat .PNG, 100, fos);
			fos.flush();
		}catch(Exception ex){
			if(DEBUG)
				Log.e(TAG, "bitmap write to file exception");
		}finally{
			if(fos!=null)
			{
				try {
					fos.close();
				} catch (Exception e) {
					
				}
			}
		}
	}
}
内容概要:本文介绍了一套针对智能穿戴设备的跑步/骑行轨迹记录系统实战方案,旨在解决传统运动APP存在的定位漂移、数据断层和路径分析单一等问题。系统基于北斗+GPS双模定位、惯性测量单元(IMU)和海拔传感器,实现高精度轨迹采集,并通过卡尔曼滤波算法修正定位误差,在信号弱环境下利用惯性导航补位,确保轨迹连续性。系统支持跑步与骑行两种场景的差异化功能,包括实时轨迹记录、多维度路径分析(如配速、坡度、能耗)、数据可视化(地图标注、曲线图、3D回放)、异常提醒及智能优化建议,并可通过蓝牙/Wi-Fi同步数据至手机APP,支持社交分享与专业软件导出。技术架构涵盖硬件层、设备端与手机端软件层以及云端数据存储,强调低功耗设计与用户体验优化。经过实测验证,系统在定位精度、续航能力和场景识别准确率方面均达到预期指标,具备良好的实用性和扩展性。; 适合人群:具备一定嵌入式开发或移动应用开发经验,熟悉物联网、传感器融合与数据可视化的技术人员,尤其是从事智能穿戴设备、运动健康类产品研发的工程师和产品经理;也适合高校相关专业学生作为项目实践参考。; 使用场景及目标:① 开发高精度运动轨迹记录功能,解决GPS漂移与断点问题;② 实现跑步与骑行场景下的差异化数据分析与个性化反馈;③ 构建完整的“终端采集-手机展示-云端存储”系统闭环,支持社交互动与商业拓展;④ 掌握低功耗优化、多源数据融合、动态功耗调节等关键技术在穿戴设备中的落地应用。; 阅读建议:此资源以真实项目为导向,不仅提供详细的技术实现路径,还包含硬件选型、测试验证与商业扩展思路,建议读者结合自身开发环境,逐步实现各模块功能,重点关注定位优化算法、功耗控制策略与跨平台数据同步机制的设计与调优。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值