Android笔记二十七.Bitmap之简易图片查看器

转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)

为了增强用户之间的交互,Android系统中提供了一些API和部件给我们开发美观有趣的应用。比如Android系统提供了ImageView来显示静态图片、AnimationDrawble来开发逐帧动画以及通过Animation对普通图片使用不减动画等。另外,Android应用中的图片不仅包括*.png、*.jpg、*.gif等格式的位图,也包括使用XML资源文件定义的各种Drawable对象。关于Drawable对象的使用,主要有以下几个方面:

(1)@drawable/file_name:在XML资源文件中通过@drawable/file_name来访问该Drawable对象;

(2)R.drawable.file_name:在Java代码中通过该图片资源的R清单文件中的索引项R.drawable.file_name来访问该Drawable对象。

(3)Resources.getDrawable(int id):由于R.drawable.file_name是一个int类型的常量,其只代表Drawable对象的ID,如果在Java程序中需要获得实际的Drawable对象,则可调用该方法来获取。

一、图片处理API

*Bitmap:代表一张位图;

*BitmapDrawable:用于封装图片,即封装的图片就是一个Bitmap对象;

*BitmapFactory:为一个工具类,用于提供大量的方法,这些方法可用于从不同的数据源来解析、创建一个Bitmap对象。

1.Bitmap类

代表一张位图(即普通的*.png、*.jpg、*.gif等格式图片),Bitmap类负责管理和转换原始位图图形,其常用方法有:

(1)从其他途径创建一个Bitmap对象

>static Bitmap createBitmap(Bitmap source,int x,int y,int width,int height):从源位图source的 指定坐标点(给定x、y)开始,从中"挖取"宽width、高height的一块处理用于创建新的Bitmap对象。

>static Bitmap createScaledBitmap(Bitmap src,iint dstWidth,int dstHeight,boolean filter):对源位图src进行缩放,缩放成宽
dstWidth、高dstHeight的新位图。

>static Bitmap createBitmap(int width,int height,Bitmap.Config
config):创建一个宽width、高height的新位图,其中Bitmap.Config为位图的配置是Bitmap的嵌入类用于描述像素是怎样存储的(ALPHA_8、ARGB_8888 、RGB_565 )。

>static Bitmap createBitmap(Bitmap
source,int x,int y,int width,int height,Matrix m,boolean filter):从源位图source的指定坐标点(给定x、y)开始,从中"挖取"宽width、高height的一块位图来创建新的Bitmap对象,并按Matrix指定的规则进行变换。

(2)获取位图的宽度、高度大小

>final int getHeight() :返回位图的高度

>final int getWidth() :返回位图的宽度

>int getScaledHeight(int targetDensity)
:返回被缩放位图的高度

>int getScaledWidth(int targetDensity)
:返回被缩放位图的宽度

(3)判断Bitmap对象是否被收回

>final boolean isRecycled()
:返回该Bitmap对象是否已被回收

>void recycle() :强制一个Bitmap对象立即回收自己

注释:这里提到Bitmap对象的回收问题,主要是因为大部分时候,我们只要把图片放在/res/drawable-mdpi目录下,就可以在程序中通过图片对象的ID来获取封装该图片的Drawable对象。但由于手机系统的内存比较小,如果系统不停地去解析、创建Bitmap对象,可能由于前面创建Bitmap所占用的内存还没有回收而导致程序运行时引发"内存溢出"错误。

2.BitmapDrawable类

BitmapDrawable类用于包装一个位图,并且该Drawable可被平铺、拉升、对齐等操作。我们可以从一个文件路径、一个输入流、XML或者Bitmap对象来创建一个BitmapDrawable对象。

(1)构造方法

>BitmapDrawable(Bitmap
bitmap)

>BitmapDrawable(Resources
res, Bitmap bitmap)

(2)常用方法

>final
Bitmap getBitmap():获取该BitmapDrawable对象对应的Bitmap对象

>final
Paint getPaint() :获取渲染该drawable的paint对象

>void
setAlpha(int alpha) :为drawable对象指定透明度

注释:我们可以使用"BitmapDrawable drawable = new BitemapDrawable(bitmap);"语句把一个Bitmao对象包装成BitmapDrawable对象;通过"Bitmap
bitmap = drawable.getBitmap()"语句来获取BitmapDrawable所包装的Bitmap对象。

3.BitmapFactory类

BitmapFactory类 为一个工具类,提供大量的方法可用于从不同的数据源来解析、创建一个Bitmap对象。比如Android应用需要访问其他存储路径(SD卡中)里的图片,都需要借助于BitmapFactory来解析和创建一个Bitmap对象。

(1)构造方法:BitmapFactory()

(2)常用方法:

>static
Bitmap  decodeByteArray(byte[] data, int offset, int length) :从指定字节数组的offset位置开始,将长度为length的字节数据解析成Bitmap对象

>static
Bitmap  decodeFile(String pathName) :从pathName指定的文件中解析、创建Bitmap对象

>static
Bitmap  decodeFileDescriptor(FileDescriptor fd):从FileDescriptor(文件描述符)对应的文件中解析、创建Bitmap对象

>static
Bitmap  decodeResource(Resources res, int id) :根据给定的资源ID从指定资源中解析、创建Bitmap对象

>static
Bitmap  decodeStream(InputStream is):从指定输入流中解析、创建Bitmap对象

二、简易图片查看器开发思路

本应用主要是实现查看/res/assets目录下所有的图片,对于图片的替换主要是调用ImageView的setImageBitmap(Bitmap
bitmap)方法。 所以,我们最终的目的就是要获得切换图片对应的Bitmap对象。具体步骤:(1)首先需要获取assets所有文件列表("AssetManager assets=getAssets();String[]  assetsImages = assets.list("");然后,(2)获取并打开字符串数数组中一张图片资源输入流(InputStream
stream = assets.open(assetsImages[currentImage])

(3) 调用Bitfactory.decodeStream(InputStream stream)方法获取该位图的Bitmap对象,最后在调用ImageView的setImageBitmap(Bitmap
bitmap)方法实现切换图片效果。

注意:由于图片的切换,系统会不停地去解析、创建Bitmap对象,所以,为了避免手机内存"溢出"情况,在切换图片之前需要判定当前Bitmap是否被收回,否者需要强制收回该图片。

BitmapDrawable bitmapDrawable
= (BitmapDrawable)imageView.getDrawable();    //获取当前图片的BitmapDrawable对象

if(bitmapDrawable != null
&& !bitmapDrawable.getBitmap().isRecycled())                //通过BitmapDrawable对象获得对应的Bitmap对象及其方法

{

bitmapDrawable.getBitmap().recycle();

}

三、源码实现

实现:开发一个查看/assets/目录下图片的图片查看器。

BitmapTest.java

<span style="font-size:18px;">package com.example.bitmaptest;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class BitmapTest extends Activity {
 private int currentImage=0;
 String[] assetsImages;
 ImageView imageView;
 AssetManager assets; // asset资源管理引用变量
 InputStream stream=null;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.mian);
  imageView = (ImageView) findViewById(R.id.imageview);
  // 1.获取/res/assets目录下文件列表
  try {
   assets = getAssets(); // 获取asset资源管理对象
   assetsImages = assets.list(""); // 获取assets目录下的所有文件名存放至String数组中
   stream=assets.open(assetsImages[currentImage]);	//ImageView设置为Assets目录下的第一张图片
   imageView.setImageBitmap(BitmapFactory.decodeStream(stream));
  } catch (IOException e) {
   e.printStackTrace();
  }
  // 2.为btn按钮注册事件监听器,实现循环图片切换功能
  Button btn = (Button) findViewById(R.id.button);
  btn.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    //a.累加数组下标currentImage
    if(!assetsImages[currentImage].endsWith("*.png") && !assetsImages[currentImage].endsWith("*.jpg") &&!assetsImages[currentImage].endsWith("*.gif"))
    {
     currentImage++;
     if(currentImage==assetsImages.length-3)	//如果发现数组越界,重置currentImage
     {
      currentImage=0;
     }
    }
    //b.打开指定资源的输入流
    InputStream stream = null;
    try {
     stream=assets.open(assetsImages[currentImage]);
    } catch (IOException e) {
     e.printStackTrace();
    }
    //c.获取当前图片的BitmapDrawable对象
    BitmapDrawable bitmapDrawable = (BitmapDrawable)imageView.getDrawable();
    if(bitmapDrawable!=null && !bitmapDrawable.getBitmap().isRecycled())
    {
        bitmapDrawable.getBitmap().recycle();
    }
    imageView.setImageBitmap(BitmapFactory.decodeStream(stream));
   }
  });
 }
}</span>

效果演示:

时间: 2024-10-02 16:53:04

Android笔记二十七.Bitmap之简易图片查看器的相关文章

javaFx 简易图片查看器V1

功能说明 1.查看在输入框内输入文件夹路径,通过点击next来查看文件夹下的.jpg图片 package sample; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.contr

Android笔记二十七.Service组件入门(一).什么是Service?

转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.Service 1.Service简介 Service为Android四大组件之一,Service与Activity组件相似,都代表可执行的程序且有自己的生命周期,唯一的区别是Activity组件提供界面方便人机交互而Service只在后台运行且没有交互界面.Service是android 系统中的一种组件,它们都是从Context派生出来的,但是它不能自己运行,只能在后台运行,并且可以和其

Android学习笔记二十七之ExpandableListView可折叠列表和StackView栈视图

Android学习笔记二十七之ExpandableListView可折叠列表和StackView栈视图 ExpandableListView可折叠列表 这一节我们介绍第三个用适配器的控件,ExpandableListView可折叠列表.这个控件可以实现我们在QQ中非常常见好友分组功能,ExpandableListView是ListView的子类,用法跟ListView差不多,下面我们来学习这个控件的基本使用: 常用属性: android:childDivider:指定各组内子类表项之间的分隔条,

angular学习笔记(二十七)-$http(5)-使用$http构建RESTful架构

在angular中有一个特别为RESTful架构而定制的服务,是在$http的基础上进行了封装. 但是为了学习,我们先看看用直接$http是如何构建RESTful架构的: 假设有一个银行卡的列表.需要的功能有: 可以通过id来获取用户123的指定id的卡     'GET'  'card/user/123/id' 可以获取用户123的所有的银行卡             'GET'  'card/user/123' 可以更新用户123的指定id的卡                'POST' '

【Unity 3D】学习笔记二十七:unity游戏脚本(七)

使用C#编写游戏脚本 在前面提到,unity支持三种语言编写脚本:js,C#,boo.入门的时候建议只用js,因为js比较简单易懂,语法也不是很严格.但后来晋级的时候推荐使用C#,因为它比较符合unity的编程思想,执行效率更高.下面总结下怎么使用C#编写脚本. 继承MonoBehaviour类 在unity中,任何一个脚本,包括上述三种语言都需要去继承MonoBehaviour这个类.为什么我们之前写JS代码的时候没有继承咧?因为在创建JS代码的时候,系统会将其类名与继承关系隐藏起来. 在pr

Android图片查看器(图片可移动、缩放)

要实现图片在手指点击后移动和缩放有好几种方法,在这里是通过onTouch来实现的. 实例代码如下: 首先是在View中有一个ImageView <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_paren

Android中的图片查看器

本案例,使用Eclipse来开发Android2.1版本的图片查看器. 1)首先,打开Eclipse,新建一个Android2.1版本的项目ShowTu,打开res/values中目录下的strings.xml,将其中代码替换成一下代码: 路径:ShowTu/res/valus/string.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="

Android 自学之网格试图(GridView)和图片切换器(ImageSwitcher)功能和用法

网格试图(GridView)用于在界面上按行,列分布的方式来显示多个组件. GridView和ListView有共同的父类:AbsListView,因此GridView和ListView具有一定的相似性.GridView和ListView的主要区别在于:ListView只是一个方向上的分布:而GridView则会在两个方向上分布. 与ListView相似的是,GridView也需要通过Adapter来提供显示数据:可以通过SimpleAdapter来为GridView提供数据,也可以通过开发Ba

Canvas---Canvas图像处理、图片查看器实现思路整理、拖动边界控制

没想到一个图片查看器花了我这么多时间,而且没做好. 现在整理下思路,然后把不足的地方记一下,日后请教他人. 基本思路: 一.图片查看器功能---缩放 要实现自由缩放,先要实现图片对canvas的自适应,就是给你一张大图片,你能够把它合理缩放后恰好绘制在canvas中. 具体做法是:例如:图片为500*500,canvas为240*320,那就取缩放宽度为240,长度为240/500*500,利用缩放宽度与长度,绘制图片即可. 然后是自由缩放,这时,你的缩小放大对象只要是一个矩形就好,然后图片去适