zoukankan      html  css  js  c++  java
  • 用getDrawingCache方法获取ImageView中的图像需要注意的问题

    转:我们知道在Android中ImageView是一个用于显示图像的控件,比如在很多联系人方面的应用中,需要为联系人拍摄头像,并将得到的头像放在一个ImageView对象中显示。通常,在没有为联系人拍摄头像之前,ImageView对象中显示的是一个缺省的图片。因此,在保存联系人头像数据时,需要比较拍摄前和拍摄后两个图像是否一致,因为拍摄后是可能取消拍摄结果的,因此有可能造成拍摄动作发生前后ImageView中显示的是同一个图像。只有当不一样时,才将ImageView对象中的图像保存到数据库中,否则不用保存,这样一方面可以提高性能,另一方面可以节省空间。

    根据上面的思路,我们可以在开始拍摄前获取ImageView对象中的图像,在保存数据的时候,再次从该ImageView对象中获取图像,然后比较先后所得到的像个图像是否一致,并进行进一步的处理。

    从ImageView对象中获取图像的方法是什么呢?

    从ImageView对象中获取图像的方法,就是ImageView类中的getDrawingCache()方法,比如下面的代码就是从一个ImageView对象iv_photo中获取图像:

    Bitmap obmp = Bitmap.createBitmap(iv_photo.getDrawingCache());

    但是需要说明的是:

    1.     在调用getDrawingCache()方法从ImageView对象获取图像之前,一定要调用setDrawingCacheEnabled(true)方法:

                iv_photo.setDrawingCacheEnabled(true);

            否则,无法从ImageView对象iv_photo中获取图像;

    2.     在调用getDrawingCache()方法从ImageView对象获取图像之后,一定要调用setDrawingCacheEnabled(false)方法:

                iv_photo.setDrawingCacheEnabled(false);

            以清空画图缓冲区,否则,下一次从ImageView对象iv_photo中获取的图像,还是原来的图像。

     

    下面,我们就用实际的例子来给予说明。

     

    1.     首先创建一个Android Project,并制定生成一个Activity,取名为Compare2Images

    2.     将图片androidlogo.png和xiaocheng.png拖入res/drawable-mdpi文件夹中,它们分别是:

             

    3.     修改main.xml,使之如下

    <?xml version="1.0"encoding="utf-8"?>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

       

        <ImageView android:id="@+id/iv_photo"

                    android:layout_width="96dip"

                    android:layout_height="96dip"

                    android:src="@drawable/androidlogo"

        />

       

        <Button android:id="@+id/btn_photo"

                    android:layout_width="93dip"

                    android:layout_height="40dip"

                    android:textSize="16dip"

                    android:text="OK"

        />

    </LinearLayout>

     

    不难看出,在main.xml中有一个ImageView对象,该对象中显示的图片是@drawable/androidlogo,其下是一个按钮。这个实验的意图是:

    a.     当touch down ImageView对象时,首先获取ImageView中显示的图像,然后启动另外一个Activity(用来模拟照相机程序),该activity返回另外一个图片(用xiaocheng.png模拟),Compare2Images在OnActivityResult方法中获取返回的图像后,将其显示在ImageView对象iv_photo中

    b.     当touch down OK按钮btn_photo时(用来模拟保存数据的动作),再次从iv_photo中获取图像,然后和a中获得的图像进行比较,并进行进一步的处理。

     

    4.     Compare2Images的代码如下:

            package com.waveline.compare2images;

            import java.io.File;

            import java.io.FileNotFoundException;

            import java.io.FileOutputStream;

            import java.io.IOException;

            import android.app.Activity;

            import android.content.Intent;

            import android.graphics.Bitmap;

            import android.graphics.Bitmap.CompressFormat;

            import android.os.Bundle;

            import android.os.Environment;

            import android.view.MotionEvent;

            import android.view.View;

            import android.view.View.OnTouchListener;

            import android.widget.Button;

            import android.widget.ImageView;

            import android.widget.Toast;

            import android.widget.ImageView.ScaleType;

     

            public class Compare2Images extends Activity

            implements

            OnTouchListener

            {

                    private Bitmap obmp;

                    private ImageView iv_photo;

                    private Button btn_photo;

                    @Override

                    public void onCreate(BundlesavedInstanceState)

                    {

                            super.onCreate(savedInstanceState);

                            setContentView(R.layout.main);

           

                            iv_photo =(ImageView)findViewById(R.id.iv_photo);

                            iv_photo.setOnTouchListener(this);

     

                            btn_photo = (Button)findViewById(R.id.btn_photo);

                            btn_photo.setOnTouchListener(this);

                   }

     

                    public boolean onTouch(View v, MotionEventevent)

                    {

                            switch(v.getId())

                            {

                            case R.id.iv_photo:

                                   if(event.getAction() ==MotionEvent.ACTION_DOWN)

                                   {

                                        // ImageView对象(iv_photo)必须做如下设置后,才能获取其中的图像

                                        iv_photo.setDrawingCacheEnabled(true);

                                       // 在ImageView对象(iv_photo)被touch down的时候,获取ImageView中的图像

                                       obmp = Bitmap.createBitmap(iv_photo.getDrawingCache());

                                       //然后在OK按钮(btn_photo)被touch down的时候,比较ImaageView对象(iv_photo)中的图像和

                                       //obmp是否一致,以便做进一步的处理,比如,如果不一致就保存,否则就不保存到数据库中。

               

                                       //从ImaggeView对象中获取图像后,要记得调用setDrawingCacheEnabled(false)清空画图缓

                                       //冲区,否则,下一次用getDrawingCache()方法回去图像时,还是原来的图像

                                       iv_photo.setDrawingCacheEnabled(false);

               

                                       // 将得到obmp写入文件

                                       FileOutputStream  m_fileOutPutStream = null;

                                       String filepath = Environment.getExternalStorageDirectory() +File.separator + "tempPhoto.png";

                                       try

                                       {

                                              m_fileOutPutStream= new FileOutputStream(filepath);

                                       }

                                       catch (FileNotFoundException e)

                                       {

                                              e.printStackTrace();

                                       }

               

                                       obmp.compress(CompressFormat.PNG, 100, m_fileOutPutStream);

               

                                       try

                                       {

                                                 m_fileOutPutStream.flush();

                                                 m_fileOutPutStream.close();

                                       }

                                       catch (IOException e)

                                       {

                                                 e.printStackTrace();

                                       }

               

                                       Intent intent = new Intent(this, TakePicture.class);

                                       startActivityForResult(intent, 1);

                            }

                           break;

               case R.id.btn_photo:

                        if(event.getAction() ==MotionEvent.ACTION_DOWN)

                       {

                                 // ImageView对象(iv_photo)必须做如下设置后,才能获取其中的图像

                                 iv_photo.setDrawingCacheEnabled(true);

                                 // 获取ImageView中的图像

                                 Bitmap sbmp =Bitmap.createBitmap(iv_photo.getDrawingCache());

                                 // 从ImaggeView对象(iv_photo)中获取图像后,要记得调用setDrawingCacheEnabled(false)

                                // 清空画图缓冲区

                                iv_photo.setDrawingCacheEnabled(false);      

                                

                                 // 将得到sbmp写入文件

                                 FileOutputStream  m_fileOutPutStream = null;

                                 String filepath = Environment.getExternalStorageDirectory() +File.separator + "tempPhoto1.png";

                                 try

                                 {

                                           m_fileOutPutStream= new FileOutputStream(filepath);

                                 }

                                 catch (FileNotFoundException e)

                                 {

                                           e.printStackTrace();

                                 }

               

                                 sbmp.compress(CompressFormat.PNG, 100, m_fileOutPutStream);

               

                                 try

                                 {

                                           m_fileOutPutStream.flush();

                                           m_fileOutPutStream.close();

                                 }

                                 catch (IOException e)

                                 {

                                           e.printStackTrace();

                                 }

               

                                 if(!compare2Image(obmp, sbmp))

                                 {

                                       Toast.makeText(this, "new picture", Toast.LENGTH_LONG).show();

                                 }

                                 else

                                 {

                                       Toast.makeText(this, "old picture", Toast.LENGTH_LONG).show();

                                 }

                      }

                      break;

               }

               return false;

          }

     

          @Override

          protected void onActivityResult(int requestCode, int resultCode, Intent data)

          {

                   if((requestCode == 1) &&(resultCode ==RESULT_FIRST_USER + 2))

                  {

                      Bitmap ret_bitmap =data.getParcelableExtra("ret_bitmap");

                      iv_photo.setScaleType(ScaleType.FIT_XY);

                      iv_photo.setImageBitmap(ret_bitmap);

                  }

               super.onActivityResult(requestCode,resultCode, data);

          }

     

          // 简单的比较两个图像是否一致

        private boolean compare2Image(Bitmap bmp1,Bitmap bmp2)

        {

              int iteration = 0;

              int width = bmp1.getWidth();

              int height = bmp1.getHeight();

              if(width != bmp2.getWidth()) return false;

              if(height != bmp2.getHeight()) return false;

       

              if(width < height)

              {

                    iteration = width;

              }

              else

              {

                    iteration = height;

              }

               

              for(int i = 0; i < iteration; ++i)

             {              

                    if(bmp1.getPixel(i, i) != bmp2.getPixel(i,i)) return false;

              }

              return true;

          }

    }

    5.     另外创建一个Activity,取名为TakePicture,并为它准备一个对应的layout文件takepicture.xml:

            <?xml version="1.0"encoding="utf-8"?>

            <LinearLayout

              xmlns:Android="http://schemas.android.com/apk/res/android"

              android:layout_width="wrap_content"

              android:layout_height="wrap_content">

     

                     <Button android:id="@+id/btn_OK"

                              android:layout_width="90dip"

                              android:layout_height="40dip"

                              android:textSize="16dip"

                              android:text="OK"

                     />

            </LinearLayout>

     

    6.     修改TakePicture.java,使其如下:

            package com.waveline.compare2images;

            import android.app.Activity;

            import android.content.Intent;

            import android.graphics.Bitmap;

            import android.graphics.BitmapFactory;

            import android.os.Bundle;

            import android.view.View;

            import android.view.View.OnClickListener;

            import android.widget.Button;

     

            public class TakePicture extends Activity

            implements

            OnClickListener

            {

                    private Intent intent;

                    private Button btn_OK;

     

                    @Override

                    protected void onCreate(BundlesavedInstanceState)

                    {

                               super.onCreate(savedInstanceState);

                               setContentView(R.layout.takepicture);

              

                               btn_OK = (Button)findViewById(R.id.btn_OK);

                               btn_OK.setOnClickListener(this);

              

                               intent = getIntent();

                    }

     

                    public void onClick(View v)

                    {

                               switch(v.getId())

                               {

                               case R.id.btn_OK:

                                     Bitmap ret_bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.xiaocheng);

                                     intent.putExtra("ret_bitmap", ret_bitmap);

                                     setResult(RESULT_FIRST_USER + 2, intent);

                                     finish();

                                     break;

                               }

                    }

          }

     

    7.     运行结果


    Touch down ImageView对象后,会出现TakePicture的界面:


    点击OK按钮,会将xiaocheng.png作为结果返回给Compare2Images,


    点击OK按钮,对前后两幅图像进行比较:


    结果显示是一副新的图像,即和原来的图像时不一样的。 

    如果在第一次调用getDrawingCache()方法从ImageView对象iv_photo获取图像之后,没有调用setDrawingCacheEnabled(false)方法,尽管iv_photo显示的图片和原来的不同,但比较的结果总是一样的,也就是说两次调用getDrawingCache()方法所得到的结果是一样的,这点应当特别需要注意。

  • 相关阅读:
    MySql 用户 及权限操作
    MAC 重置MySQL root 密码
    在mac系统安装Apache Tomcat的详细步骤[转]
    Maven:mirror和repository 区别
    ES6 入门系列
    转场动画CALayer (Transition)
    OC 异常处理
    Foundation 框架
    Enum枚举
    Invalid App Store Icon. The App Store Icon in the asset catalog in 'xxx.app' can’t be transparent nor contain an alpha channel.
  • 原文地址:https://www.cnblogs.com/nongzha/p/3042480.html
Copyright © 2011-2022 走看看