bitmap使用全程记录

今天做了一个简单的应用,大致是向服务器请求一张图片,然后点击跳转到另外一个界面上使得这张图片可以自由伸缩。

首先是在ActivityA中请求图片,使用Ajax请求,代码如下所示。

		 // 2014.5.12晚
		 AQuery aq = new AQuery(RepairInfoDetail.this);
		 mViewPhotoText = (TextView) findViewById(R.id.photoText);
		 mViewPhotoText.setText("现场照片:拍摄于" + map.get("reportTime").toString().substring(0, 10));
		 aq.id(R.id.inspectionPhoto).image(map.get("inspectionPhoto").toString(), true, true, 200, 0);

而后手机上会显示一个小图片,给用户看的时候反馈这个图片有点小,应该有放大功能,根据需求最终决定跳转到另一个ActivityB中。这里问题出来了:在新的界面上再次请求图片,会导致图片的重复下载,加载过程还特别慢;如果可以将bitmap这个对象直接通过bundle存储、传到另一个界面,就省了之前的问题。

之前用的方法并不是AQuery,而是流和多线程操作的方法(上一篇文章应该写过),因此bitmap可以轻松获得。但在传递bitmap的时候,发现Activity无论如何传递,都很容易报OOP的错误(Out of Memory,内存溢出),图片文件过大,即便整成流还是整成全局变量都容易出错。因此Activity传递bitmap对象这种思路被彻底否定。

通过查Android文档,AQuery已经给好了很完整有效的缓存机制,大致意思如下:如果某次请求服务器已经根据某url请求了对应的图片资源,那么在下次请求这个图片资源时,该url会自动被AQuery识别并从缓存中读取,而不是再次请求服务器。这样就不存在图片重复下载、加载过程慢的问题了。

OK,这样Activity跳转过程结束,新的Activity也同样通过AQuery得到图片并加载到了layout中的imageview控件中。问题是,如何获得bitmap对象以进一步适用图片伸缩等操作的代码?

从AQuery那段代码可以看到aq方法直接将url对应的图片文件加载到了R.id.inspectionPhoto对应的控件当中,并没有显示出现bitmap对象。找了很多种方法,最后发现aq这个方法竟然有callback!而callback恰好是bitmapAjaxCallback!好吧,复写callback函数,就可以对bitmap做任何事情了。

两段完整代码如下:

package ouc.sei.civil_defend.ui;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

import com.androidquery.AQuery;

import ouc.sei.civil_defend.R;
import android.app.Activity;
import android.app.DownloadManager.Query;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * 某条维修信息细节查看
 *
 * @author GloryZSG
 *
 */
public class RepairInfoDetail extends Activity {
	private TextView repairname;
	private TextView repairtype;
	private TextView repairlevel;
	private TextView repairtime;
	private TextView districtName;
	private ImageView  mImgViewPhoto;
	private Bitmap mybitmap;
	private TextView mViewAppearance;
	private TextView mViewElectricity;
	private TextView mViewSound;
	private TextView mViewWorkState;
	private TextView mViewPhotoText;
	private Handler handler;
	 private Bitmap bm;
	 private HashMap<String,Object> map;
	 //----------------------
	private Button imageButton;

	@SuppressWarnings("unchecked")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.repairinfodetail);

		handler = new Handler();
		map = new HashMap<String,Object>();
		 try {
	            Bundle bundle = getIntent().getExtras();
	            Serializable data = bundle.getSerializable("repairinfo");
	            if (data != null) {
	            	map = (HashMap<String, Object>)data;
	            } else {
	                return;
	            }
	     } catch (Exception e) {
	           e.printStackTrace();
	     }
		 //final String checkid= map.get("id").toString();
		 // 设备名称
		 repairname = (TextView) findViewById(R.id.repairname);
		 repairname.setText("设备名称:" + map.get("equipmentName").toString());
		 // 设备类型
		 repairtype = (TextView) findViewById(R.id.repairtype);
		 repairtype.setText("设备类型:" + map.get("regionalType").toString());

		 districtName = (TextView) findViewById(R.id.districtName);
		 districtName.setText("所在区域:" + map.get("districtName").toString());

		 repairlevel=(TextView) findViewById(R.id.repairlevel);
		 repairlevel.setText("故障级别:"+map.get("faultLevel").toString());

		 repairtime=(TextView) findViewById(R.id.inspector);
		 repairtime.setText("巡查人员:"+map.get("inspector").toString());

		 repairtime=(TextView) findViewById(R.id.repairtime);
		 repairtime.setText("巡查时间:"+map.get("reportTime").toString());

		 mViewAppearance = (TextView) findViewById(R.id.appearance);
		 mViewAppearance.setText("外观状况:" + map.get("appearance").toString());

		 mViewElectricity = (TextView) findViewById(R.id.electricity);
		 mViewElectricity.setText("通电情况:" + map.get("electricity").toString());

		 mViewSound=(TextView) findViewById(R.id.sound);
		 mViewSound.setText("声音测试:" + map.get("sound").toString());

		 mViewWorkState=(TextView) findViewById(R.id.workState);
		 mViewWorkState.setText("运转状态:" + map.get("workState").toString());		

		 // 好开心啊,又学新知识了! 2014.5.12晚
		 AQuery aq = new AQuery(RepairInfoDetail.this);
		 mViewPhotoText = (TextView) findViewById(R.id.photoText);
		 mViewPhotoText.setText("现场照片:拍摄于" + map.get("reportTime").toString().substring(0, 10));
		 aq.id(R.id.inspectionPhoto).image(map.get("inspectionPhoto").toString(), true, true, 200, 0);

//	     if(bm != null) {
//			 mViewPhotoText.setText("现场照片:拍摄于" + map.get("reportTime").toString().substring(0, 10));
//			 imageButton.setVisibility(View.VISIBLE);
//		 }
//		 else {
//			 mViewPhotoText.setText("现场照片:暂无");
//		 }
		 // // 关联布局控件,加载到布局文件中
//		 mImgViewPhoto = (ImageView) findViewById(R.id.inspectionPhoto);
//		 mImgViewPhoto.setImageBitmap(bm);		

//		 new Thread() {
//			 public void run() {
////				  (2014.5.1第一种方法)通过服务器返回的图片url,再次向服务器请求,添加动态新闻图片
////				  读取Bitmap图片
//				 try {
//					 AQuery aq = new AQuery(RepairInfoDetail.this);
//					 URL url;
//					 url = new URL(map.get("inspectionPhoto").toString());
//					 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//					// aq.id(R.id.inspectionPhoto).image(map.get("inspectionPhoto").toString(), true, true, 200, 0);
//					 InputStream is = conn.getInputStream();
//					 bm = BitmapFactory.decodeStream(is);
//
//				 } catch (MalformedURLException e) {
//					 // TODO Auto-generated catch block
//					 e.printStackTrace();
//				 } catch (IOException e) {
//					 e.printStackTrace();
//				 }
//				 handler.post(runnableUI);
//			 }
//		 }.start();
//
//
//		 imageButton.setVisibility(View.VISIBLE);
		 imageButton = (Button) findViewById(R.id.imageButton);
		 imageButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub				

				Intent intent = new Intent();
				intent.setClass(RepairInfoDetail.this, RepairImage.class);
				intent.putExtra("bitmap", map.get("inspectionPhoto").toString());
				startActivity(intent);
			}
		});
	}
//
//	/**
//	 * 读取图片的线程
//	 *
//	 * @author GloryZSG
//	 */
//	Runnable runnableUI = new Runnable() {
//			public void run() {
//				// (2014.5.1第一种方法)通过服务器返回的图片url,再次向服务器请求,添加动态新闻图片
//				// 读取Bitmap图片
//				// 加载到布局文件中
//				 // 调整现场照片信息
//				 mViewPhotoText = (TextView) findViewById(R.id.photoText);
//				 if(bm != null) {
//					 mViewPhotoText.setText("现场照片:拍摄于" + map.get("reportTime").toString().substring(0, 10));
//					 imageButton.setVisibility(View.VISIBLE);
//				 }
//				 else {
//					 mViewPhotoText.setText("现场照片:暂无");
//				 }
//				 // // 关联布局控件,加载到布局文件中
//				 mImgViewPhoto = (ImageView) findViewById(R.id.inspectionPhoto);
//				 mImgViewPhoto.setImageBitmap(bm);
//
//			}
//		};

	@Override
	public void onDestroy() {

		if(mybitmap!=null && !mybitmap.isRecycled())
			mybitmap.recycle();
		super.onDestroy();

	}

}

以上这段中屏蔽的关于多线程和流请求的代码没有删,这只是另外一种方法。

以下是另外一个Activity。

package ouc.sei.civil_defend.ui;

import com.androidquery.AQuery;
import com.androidquery.callback.BitmapAjaxCallback;
import com.androidquery.callback.AjaxStatus;
import ouc.sei.civil_defend.R;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class RepairImage extends Activity implements OnTouchListener{

	public static final int RESULT_CODE_NOFOUND = 200;  

    Matrix matrix = new Matrix();
    Matrix savedMatrix = new Matrix();
    DisplayMetrics dm;
    ImageView imgView;
    Bitmap bitmap;  

    /** 最小缩放比例*/
    float minScaleR = 1.0f;
    /** 最大缩放比例*/
    static final float MAX_SCALE = 10f;  

    /** 初始状态*/
    static final int NONE = 0;
    /** 拖动*/
    static final int DRAG = 1;
    /** 缩放*/
    static final int ZOOM = 2;  

    /** 当前模式*/
    int mode = NONE;  

    PointF prev = new PointF();
    PointF mid = new PointF();
    float dist = 1f;  

    private String url;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.repairimage); 

		 // 获取图片资源
		Intent intent = getIntent();
		url = intent.getStringExtra("bitmap");	

		imgView= (ImageView) findViewById(R.id.repairImageView);
					AQuery aq = new AQuery(RepairImage.this);
					aq.id(R.id.repairImageView).image(url, true, true, 400, 0,new BitmapAjaxCallback(){

				        @Override
				        public void callback(String url, ImageView iv, Bitmap bm, AjaxStatus status){				        	

				        bitmap=bm;
				        imgView.setImageBitmap(bitmap);
				         imgView.setOnTouchListener(RepairImage.this);// 设置触屏监听
				         dm = new DisplayMetrics();
				         getWindowManager().getDefaultDisplay().getMetrics(dm);// 获取分辨率
				         minZoom();
				         center();
				         System.out.println(matrix.toString());
				         imgView.setImageMatrix(matrix);
				        }

				 });
	}	

	public void SureOnClick(View v)
    {  

    }  

    /**
     * 触屏监听
     */
    public boolean onTouch(View v, MotionEvent event) {  

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        // 主点按下
        case MotionEvent.ACTION_DOWN:
            savedMatrix.set(matrix);
            prev.set(event.getX(), event.getY());
            mode = DRAG;
            break;
        // 副点按下
        case MotionEvent.ACTION_POINTER_DOWN:
            dist = spacing(event);
            // 如果连续两点距离大于10,则判定为多点模式
            if (spacing(event) > 10f) {
                savedMatrix.set(matrix);
                midPoint(mid, event);
                mode = ZOOM;
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            //savedMatrix.set(matrix);
            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == DRAG) {
                matrix.set(savedMatrix);
                matrix.postTranslate(event.getX() - prev.x, event.getY()
                        - prev.y);
            } else if (mode == ZOOM) {
                float newDist = spacing(event);
                if (newDist > 10f) {
                    matrix.set(savedMatrix);
                    float tScale = newDist / dist;
                    matrix.postScale(tScale, tScale, mid.x, mid.y);
                }
            }
            break;
        }
        //if(imgView)
        imgView.setImageMatrix(matrix);
        CheckView();
        return true;
    }  

    /**
     * 限制最大最小缩放比例,自动居中
     */
    private void CheckView() {
        float p[] = new float[9];
        matrix.getValues(p);
        if (mode == ZOOM) {
            if (p[0] < minScaleR) {
                //Log.d("", "当前缩放级别:"+p[0]+",最小缩放级别:"+minScaleR);
                matrix.setScale(minScaleR, minScaleR);
            }
            if (p[0] > MAX_SCALE) {
                //Log.d("", "当前缩放级别:"+p[0]+",最大缩放级别:"+MAX_SCALE);
                matrix.set(savedMatrix);
            }
        }
        center();
    }  

    /**
     * 最小缩放比例,最大为100%
     */
    private void minZoom() {  

        minScaleR = Math.min(
                (float) dm.widthPixels / (float) bitmap.getWidth(),
                (float) dm.heightPixels / (float) bitmap.getHeight());
        System.out.println(minScaleR);
        if (minScaleR < 1.0) {
            matrix.postScale(minScaleR, minScaleR);
        }
    }  

    private void center() {
        center(true, true);
    }  

    /**
     * 横向、纵向居中
     */
    protected void center(boolean horizontal, boolean vertical) {  

        Matrix m = new Matrix();
        m.set(matrix);
        RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
        m.mapRect(rect);  

        float height = rect.height();
        float width = rect.width();  

        float deltaX = 0, deltaY = 0;  

        if (vertical) {
            // 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移
            int screenHeight = dm.heightPixels;
            if (height < screenHeight) {
                deltaY = (screenHeight - height) / 2 - rect.top;
            } else if (rect.top > 0) {
                deltaY = -rect.top;
            } else if (rect.bottom < screenHeight) {
                deltaY = imgView.getHeight() - rect.bottom;
            }
        }  

        if (horizontal) {
            int screenWidth = dm.widthPixels;
            if (width < screenWidth) {
                deltaX = (screenWidth - width) / 2 - rect.left;
            } else if (rect.left > 0) {
                deltaX = -rect.left;
            } else if (rect.right < screenWidth) {
                deltaX = screenWidth - rect.right;
            }
        }
        matrix.postTranslate(deltaX, deltaY);
    }  

    /**
     * 两点的距离
     */
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }  

    /**
     * 两点的中点
     */
    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }  

}

bitmap使用全程记录

时间: 2024-11-01 15:00:03

bitmap使用全程记录的相关文章

ElasticSearch在linux上的安装部署全程记录

原文地址:http://www.cnblogs.com/tianjixiaoying/p/4316011.html 由于项目需求,需要在linux平台搭建一套ES服务.在搭建过程中,遇到各种各样的问题.后来都一一解决.现在要记录下来这个过程,以及其中遇到的问题,及其解决方法. 一.环境配置 操作系统:Cent OS 7 ElasticSearch版本:1.4.1 JDK版本:1.7 SSH Secure Shell版本:3.2.9 elasticsearch-servicewrapper :ES

SAP+DB2 糟糕的报表查询『ZCOR0015』 优化全程记录

ZCOR0015的优化全过程记录文档 2015年3月,今天无意翻到这篇写于2010年7月的文档,回想那时的工作,毕业3年初出茅庐的我面对接触不多的SAP+DB2竟敢操刀动斧,自信满满. 虽然这过程一路坎坷,数次判断几乎全都被打脸验证,看着如小强般坚毅的我,哈哈~ 文档里带着情绪的措词十分逗笑,可以洞悉那时的心情. ——如今5年过去,却久未闻硝烟,怀念ing~ 目录: ZCOR0015的优化全过程记录文档... 1 内容说明:1 1.寻找问题点,切入分析... 2 2.再次碰到问题,转折点.. 6

oracle12c及PLSQL Developer安装全程记录

一.登陆oracle下载页面  http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 下载适合自己电脑版本的oracle ,oracle 12c只有64位版本的,如图  选择第一个,下载 file1 和 file 2,下载后解压到同一文件夹database,先解压file1,即winx64_12102_database_1of2,选择解压到当前文件夹 然后解压file2,即winx64

基于VMware10安装CentOS6.5全程记录

下载CentOS安装光盘 :http://mirrors.aliyun.com/centos/ http://mirrors.aliyun.com/centos/6.5/isos/i386/CentOS-6.5-i386-bin-DVD1.iso http://mirrors.aliyun.com/centos/6.5/isos/i386/CentOS-6.5-i386-bin-DVD2.iso 1,创建新的虚拟机并添加CentOS6.5的安装光盘 (1)创建新的虚拟机-->选custom(ad

首次写PHP全程记录

公司客户端需要一个“气温累积”,那么这个气温从哪来呢,经查,我决定用中国气象网的接口得到.即:1.在服务器上每天定时或手动读取中国气象网的接口得到每个城市的该日json:2.解析并保存到mysql:3.客户端访问mysql得到数据集. 以上是思路.我决定用一下PHP. 步骤如下: 一.安装swampServer 二.新建数据库:单击右下角的绿色小图标,打开其中的phpMyAdmin,我新建了数据库weather,两个表citycode和weather,SQL语句如下(初步是这样,有预留): CR

.NET程序迁移到Mysql的极简方案——让GGTalk同时支持Sqlserver与mysql全程记录!

园子里的这个GGTalk,咱们前前后后用它移花接木做的IM项目也不下三四个了.初次入手的时候,洋洋代码,多少感觉有些难以把握.不过一来二去,理清了头绪,也就一览无余了.相信跟我们一样想要利用GGTalk的同学大有人在,于是我打算写这样一个<GGTalk源码详解系列>,把自己对GGTalk的梳理分享给大家,让大家更容易上手. 之前有一个企业级的IM项目,我们用GGTalk改造的,但是要求使用Mysql数据库,所以花了一番功夫将GGTalk迁移到的Mysql,功夫不负有心人,总算弄出了个成果.如今

linux安装navicat全程记录

国庆期间自己在试着用linux(ubuntu),献上navicat安装方法,以及很多教程里没有写的一些小东西 step1: 去navicat官网下载安装包,网址:http://www.navicat.com/en/download/download.html step2:进入下载目录,解压压缩包:tar -zxvf navicat120_mysql_en.tar.gz (目前最新版) step3:复制/移动目录到你想安装的目录,cp/mv step4: cd进入安装目录找到start_navic

php_Symfony_项目实战全过程记录

今天是2017年1月8号,正式接收到一个Symfony 的项目,准备全程记录遇到的问题及解决方法,之前被通知学习该框架,只是一直没有机会做项目,今天终于可以做了,希望2017把Symfony学的能会使用,能够解决基本问题,能够独立新建项目.....2017开始了........ ------------------------------------------------------------------------------------------------- 1月8号,更新代码,由于

Android中的File文件存储及读取file中的Bitmap

今年看了下android的文件存储,大致和java实现差不多 android提供了如下两个方法来打开本应用程序的数据文件的IO流: FileInputStream  openFileInput(fileName);  //输入流 FileOutputStream outputStream = openFileOutput(fileName, MODE_PRIVATE);  //输出流 打开输出流的方法的第二个是表示打开文件的mode,大概有一下几种: MODE_PRIVATE : 该文件只能被当