Camera的学习,图片的保存(两种),获取手机图片以及图片信息修改(小的图片浏览器)

在Android上,可以通过使用意图来使用设备上的某些软件。所有带有合适硬件(摄像头)的原版Android都会带有照相功能的应用程序。Camera应用程序中包含了一个意图过滤器,它使得我们可以通过意图调用系统应用,而不需要我们自己编写。意图过滤器是程序员用于指定程序能够提供某个特定功能的一种方法。在应用程序的AndroidManifest.xml文件中制定一个意图过滤器,将会告诉Android,这个应用程序将根据这个指令执行特定的任务。

Camera应用中指定了一下意图过滤器

<intent-filter>

<action android:name="android.media.action.IMAGE_CAPTURE"/>

<category android:name="android.intent.category.DEFAULT"/>

</intent-filter>

所以我们可以通过意图调用系统照相应用程序

Intent intent=new Intent("android.media.action.IMAGE_CAPTURE");或

Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTRUE);(推荐使用)

startActivity(intent);

以上两种任选一种

虽然我们现在可以调用系统拍照程序,但是这样毫无意义,我们还应该得到它的返回数据(图片)

Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTRUE);(推荐使用)

startActivityForResult(intent);

这样开启拍照程序我们能通过重写onActivityResult()方法获取返回的数据(bitmap对象....)

完整代码如下所示

<span style="font-size:14px;">package com.example.camerademo;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity implements OnClickListener{
	public static final int REQUEST_CODE=0;
	private Button paizhaoBt;
	private ImageView photoIv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		initListener();
	}
	private void initListener() {
		paizhaoBt.setOnClickListener(this);
	}
	private void initView() {
		paizhaoBt=(Button) findViewById(R.id.paizhao);
		photoIv=(ImageView) findViewById(R.id.photo_iv);
	}
	@Override
	public void onClick(View v) {
		Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
		startActivityForResult(intent, REQUEST_CODE);
	}
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(resultCode==RESULT_OK){
			//Camera返回给我们的附加数据
			Bundle bundle=data.getExtras();
			//从附加值中获取bitmap对象
			Bitmap bitmap=(Bitmap) bundle.get("data");
			//使用setImageBitmap将照片显示在界面上
			photoIv.setImageBitmap(bitmap);
		}
	}
}
</span>
<span style="font-size:14px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/paizhao"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照" />

    <ImageView
        android:id="@+id/photo_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

</LinearLayout><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/paizhao"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照" />

    <ImageView
        android:id="@+id/photo_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

</LinearLayout></span>

当运行以上程序得到的图片很小,它是被处理过了的。当通过一个意图触发时,Camera应用程序不会将原图返回给调用程序,因为这样需要消耗大量的内存,返回的是一幅缩略图
那么如何获取原始图片并显示在手机上呢

1.图片保存

从Android1.5开始,在大多数设备上可以将一个附加值传递给触发Camera应用程序的意图,MediaStore类中的EXTRA_OUTPUT常量,这个附加值常量将以URI的方式封装图片的保存路径,将图片以文件的方式存储起来。

例如:

//获取根路径
File root=Environment.getExternalStorageDirectory();
//保存的图片文件
imageFile=new File(root, "test.jpg");
Uri uri=Uri.fromFile(imageFile);
Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, REQUEST_CODE);

通过以上代码如果照相完成,图片将保存到imageFile文件中

2.图片显示

因为原始图片较大,加载到程序会耗内存,我们必须先将其压缩,Android中提供了BitmapFactory这个类对bitmap对象进行处理

例如: BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize=8;
BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);

photoIv.setImageBitmap(bitmap);

上诉代码是将图片大小压缩到原始图片的1/8,这种没有考虑图片的原始大小和屏幕大小,为了适应屏幕我们计算出一个压缩比率,再进行压缩

完整代码如下

<span style="font-size:14px;">package com.example.camerademo;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity implements OnClickListener{
	public static final int REQUEST_CODE=0;
	private Button paizhaoBt;
	private ImageView photoIv;
	private File imageFile;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		initListener();
	}
	private void initListener() {
		paizhaoBt.setOnClickListener(this);
	}
	private void initView() {
		paizhaoBt=(Button) findViewById(R.id.paizhao);
		photoIv=(ImageView) findViewById(R.id.photo_iv);
	}
	@Override
	public void onClick(View v) {
		//获取根路径
		File root=Environment.getExternalStorageDirectory();
		//保存的图片文件
		imageFile=new File(root, "test.jpg");
		Uri uri=Uri.fromFile(imageFile);
		Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
		intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
		startActivityForResult(intent, REQUEST_CODE);
	}
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(resultCode==RESULT_OK){
			//获取屏幕宽高
			int screenWidth=getWindowManager().getDefaultDisplay().getWidth();
			int screenHeight=getWindowManager().getDefaultDisplay().getHeight();
			//获取图片的宽高
			BitmapFactory.Options options=new BitmapFactory.Options();
			//只返回图片的范围大小,不解码图片本身
			options.inJustDecodeBounds=true;
			BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
			int imgWidth=options.outWidth;
			int imgHeight=options.outHeight;
			//求压缩比率,取整
			int widthRadio=(int) Math.ceil(imgWidth/screenWidth);
			int heightRadio=(int) Math.ceil(imgHeight/screenHeight);
			//那个比率大的,作为压缩比率
			options.inSampleSize=widthRadio>heightRadio?widthRadio:heightRadio;
			//解码图片
			options.inJustDecodeBounds=false;
			Bitmap bitmap=BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
			photoIv.setImageBitmap(bitmap);
		}
	}
}
</span>

<span style="font-size:14px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/paizhao"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照" />

    <ImageView
        android:id="@+id/photo_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

</LinearLayout></span>


上面我们将拍照后的图片存储到sdcard中的文件中,下面我们学习将图片存储到MediaStore中(获取图片标准路径并存储)


Android有一种在应用程序之间共享数据的方法,负责这个功能的类为内容提供者ContentProvider,内容提供者为不同类型数据的存储和检索提供了一个标准接口。

图像、音频、视频的标准内容提供者为MediaStore。MediaStore在设备上的一个标准位置存放文件,为存储和检索该文件的元数据提供便利 。什么是元数据呢?元数据是关于数据的数据,包括文件本身的数据信息,如大小名称等

和上面一样,我们要先获取图片的uri(图片存储位置)

为了获取存储图片的标准位置,首先获得MediaStore(内容提供者)的引用。使用内容解析者(ContentResolver)访问内容提供者(MediaStore)

这里我们需要传递一个特定的URI,使用的URI包含在android.provider.MediaStore.Images.Media类中的常量

1.EXTERNAL_CONTENT_URI将图片存储到外部存储器中

2.INTERNAL_CONTENT_URI将图片存储到内存中

存储图片,视频,音频等内容比较大,推荐使用第一种方式存储

由于是插入一张新图片到内容提供者所以要用insert方法

Uri uri=getContentResolver().insert(Media.EXTERNAL_CONTENT_URI,new ContentValues());

Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTRUE);

intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,uri);

在上述代码中创建了一个ContentValues对象,该对象用于保存我们在创建图片时相关联的元数据,这里我们传入了一个空对象

下面我们给ContentValues对象中添加数据,ContentValues对象存储着名值对数据

名:主要是android.provider.MediaStore.Images.Media类中的常量(这些常量位于MediaStore.MediaColumns中,由Media类实现该接口)

ContentValues values=new ContentValues(3);

values.put(Media.DIAPLAY_NAME,"TEXT");//图片名字

values.put(Media.DESCRIPTION,"TEXT");//图片描述

values.put(Media.MIME_TYPE,"image/jpeg");//文件类型

//添加一条新纪录。insert方法返回新纪录的uri

Uri uri=getContentResolver().insert(Media.EXTERNAL_CONTENT_URI,values);

返回的URI,将通过意图传递给Camera应用程序,以指定该图像应该保存的位置

URI格式:content://media/external/images/media/16


下面我们怎样来找到刚刚存储到MediaStore中的图片呢?

同保存到sdcard中的图片一样,我们同样要使用到BitmapFactory这个类,来解析图片

如下:

Bitmap bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(uri),null,options);

这里我们是通过内容解析者为图片打开一个Inputstream,然后通过BitmapFactory对流解析


那么以后我们要对图片数据进行修改怎么办呢?

内容解析者为我们提供了update方法,可以对数据进行修改更新

ContentValues values=new ContentValues(3);

values.put(Media.DIAPLAY_NAME,"hehe");//图片名字

values.put(Media.DESCRIPTION,"hehe");//图片描述

getContentResolver().update(uri,values,null,null);


完整代码如下

<span style="font-size:14px;">package com.example.camerademo;

import java.io.File;
import java.io.FileNotFoundException;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore.Images.Media;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity implements OnClickListener{
	public static final int REQUEST_CODE=0;
	private Button paizhaoBt;
	private ImageView photoIv;
	private Uri uri;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		initListener();
	}
	private void initListener() {
		paizhaoBt.setOnClickListener(this);
	}
	private void initView() {
		paizhaoBt=(Button) findViewById(R.id.paizhao);
		photoIv=(ImageView) findViewById(R.id.photo_iv);
	}
	@Override
	public void onClick(View v) {
		//创建ContentValues对象用于存储图片信息
		ContentValues values=new ContentValues(3);
		values.put(Media.DISPLAY_NAME, "test");//图片名称
		values.put(Media.DESCRIPTION, "test");//图片描述
		values.put(Media.MIME_TYPE, "image/jpeg");//文件类型
		//获取内容解析者将图片文件存储到MediaStore中
		uri=getContentResolver().insert(Media.EXTERNAL_CONTENT_URI,new ContentValues());
		Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
		intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
		startActivityForResult(intent, REQUEST_CODE);
	}
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(resultCode==RESULT_OK){
			try {
				//获取屏幕宽高
				int screenWidth=getWindowManager().getDefaultDisplay().getWidth();
				int screenHeight=getWindowManager().getDefaultDisplay().getHeight();
				//获取图片的宽高
				BitmapFactory.Options options=new BitmapFactory.Options();
				//只返回图片的范围大小,不解码图片本身
				options.inJustDecodeBounds=true;
				BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
				int imgWidth=options.outWidth;
				int imgHeight=options.outHeight;
				//求压缩比率,取整
				int widthRadio=(int) Math.ceil(imgWidth/screenWidth);
				int heightRadio=(int) Math.ceil(imgHeight/screenHeight);
				//那个比率大的,作为压缩比率
				options.inSampleSize=widthRadio>heightRadio?widthRadio:heightRadio;
				//解码图片
				options.inJustDecodeBounds=false;
				Bitmap bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
				photoIv.setImageBitmap(bitmap);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
	}
}
</span>
<span style="font-size:14px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/paizhao"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照" />

    <ImageView
        android:id="@+id/photo_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

</LinearLayout></span>

下面我们来继续学习从MediaStore中获取图片的方法

上面获取图片是通过调用摄像头后获取的单张图片,当我们不需要摄像头,只需要查看我们MediaStore库中的图片,我们到底该怎么做呢?

其实内容提供者MediaStore是以数据库的形式来存储数据的

为了执行查询,我们需要用到managedQuery方法

参数说明:第一个参数,uri

第二个参数,列名称的数组

第三个参数,where子句

第四个参数,where子句参数

第五个参数,order by子句

首先我们要创建一个需要返回的列的字符串数组

String[]columns={Media.DATA,Media._ID,Media.TITLE,Media.DISPLAY_NAME};

//返回整个图库的记录,也可条件查找

Cursor cursor=managedQuery(Media.EXTERNAL_CONTENT_URI,columns,null,null,null);

返回的游标cursor中有我们当前选择的每个列的索引

String colunmIndex=cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

为了从列表中选择字段我们需要使用索引查找

if(moveToFirst()){//确保游标有效并包含数据

String imgName=cursor.getString(colunmIndex);

}

怎样获取图片内部元数据EXIF呢?什么是EXIF?

EXIF表示可交换的图像文件格式,它是在图像文件中保存元数据的一种标准方式。EXIF数据实际上是图像文件的一部分,因此当图像位置发生变化时,应保存好EXIF

Exif是一种图像文件格式,它的数据存储于JPEG格式是完全相同的,实际上Exif格式就是JPEG格式头插入了数码照片的信息,包括拍摄的光圈、快门、平衡白、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码以及GPS等。简单来说,Exif=拍摄参数+JPED。因此,可以利用任何可以查看JPEG文件的看图软件浏览Exif信息,但是并不是所有图形程序都能处理Exif信息,而自Android2.0之后,加入了对图片Exif数据的支持。

ExifInterface

   在Android下,通过ExifInterface类操作图片的Exif信息,虽然这个类的名字包含Interface,但它不是一个接口,它是一个类,处于"android.media.ExifInterface"包下,是媒体库的一部分功能的实现。ExifInterface有一个构造函数,接受一个String类型的数据,此为读取图片文件的地址。

  Exif数据在图片中可以理解为Key-value键值对的方式存储,一般通过如下几个方法操作:

  • String getAttribute(String tag):获取图片中属性为tag的字符串值。
  • double getAttribute(String tag,double defaultValue):获取图片中属性为tag的double值。
  • int getAttributeInt(String tag,defaultValue):获取图片中属性为tag的int值。
  • void setAttribute(String tag,String value):根据输入参数,设定图片Exif的值。
  • void saveAttrubutes():把内存中图片的Exif写入到图片中。

  可以看到,上面大部分方法操作了一个String类型的tag参数,此为Exif的属性,在ExifInterface中定义了一些字符串的静态常量表示这些tag值,常用如下:

  • TAG_APERTURE:光圈值。
  • TAG_DATETIME:拍摄时间,取决于设备设置的时间。
  • TAG_EXPOSURE_TIME:曝光时间。
  • TAG_FLASH:闪光灯。
  • TAG_FOCAL_LENGTH:焦距。
  • TAG_IMAGE_LENGTH:图片高度。
  • TAG_IMAGE_WIDTH:图片宽度。
  • TAG_ISO:ISO。
  • TAG_MAKE:设备品牌。
  • TAG_MODEL:设备型号,整形表示,在ExifInterface中有常量对应表示。
  • TAG_ORIENTATION:旋转角度,整形表示,在ExifInterface中有常量对应表示。
用法:

 ExifInterface exifInterface = new ExifInterface("/sdcard/a.jpg");

 String FFNumber = exifInterface.getAttribute(ExifInterface.TAG_APERTURE);
 String FDateTime = exifInterface.getAttribute(ExifInterface.TAG_DATETIME);
 String FExposureTime = exifInterface.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
 String FFlash = exifInterface.getAttribute(ExifInterface.TAG_FLASH);
 String FFocalLength = exifInterface.getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
 String FImageLength = exifInterface.getAttribute(ExifInterface.TAG_IMAGE_LENGTH);
 String FImageWidth = exifInterface.getAttribute(ExifInterface.TAG_IMAGE_WIDTH);
 String FISOSpeedRatings = exifInterface.getAttribute(ExifInterface.TAG_ISO);
 String FMake = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
 String FModel = exifInterface.getAttribute(ExifInterface.TAG_MODEL);
 String FOrientation = exifInterface.getAttribute(ExifInterface.TAG_ORIENTATION);
 String FWhiteBalance = exifInterface.getAttribute(ExifInterface.TAG_WHITE_BALANCE);


我们如何将EXIF信息写入到图像中呢?

Exif信息在图片中以二进制的形式存储,每个字段存储的数据位数是固定的,并且tag的数量也是固定,所以我们只能操作图片Exif信息中已经存在的tag的值,并且保存的数据要依照它存储位数的限制,如果存储的数据类型错误,将会导致存储的数据可能无法正确的取出,超出位数将被截取。如无法将TAG_ORIENTATION中存储一个字符串的数据,它必须存储int类型的值,多出来的将被截取

saveAttributes()方法主要用于把内存中所有当前Exif信息保存到目标图片中,依照官方文档的解释,它是一个低效率的,它会把图片的所有Exif信息,重新依次保存到目标图片,所以推荐使用setAttribute()方法进行设置Exif信息。但是在实际应用中发现,如果仅使用setAttribute()设置Exif信息,将不会写入到目标图片中,只有在改变Exif信息后,调用saveAttribute()才可以把新的Exif写入到目标图片中。这个过程效率比较低,模拟器上会卡顿一下,但是真机测试没有这样的情况,反应很快。

用法:

// 获取图片Exif
ExifInterface exif = new ExifInterface("/sdcard/a.jpg");
// 保存指定tag的值
exif.setAttribute(strAttr,strValue);
// 把Exif信息写入目标图片
exif.saveAttributes();

需要添加以下权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


下面是一个读取手机全部图片,并修改图片的EXIF信息,并读取信息的完整代码

activity中的代码

<span style="font-size:14px;">package com.example.photoalbumdemo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.database.Cursor;
import android.media.ExifInterface;
import android.os.Bundle;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Gallery;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
	//存储手机中的所有图片地址
	private List<String> imgUrls=new ArrayList<>();
	//显示图片总数
	private TextView imgNumTv;
	//用于展示图片
	private Gallery gallery;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		imgNumTv=(TextView) findViewById(R.id.photoNum);
		gallery=(Gallery) findViewById(R.id.gallery1);
		//需要查询的图片属性数组
		String[]columns={Media.DATA,Media._ID,Media.TITLE,Media.DISPLAY_NAME};
		//查询出来后,返回的Cursor对象,存储着图片信息
		Cursor cursor=managedQuery(Media.EXTERNAL_CONTENT_URI, columns, null, null, null);
		//获取图片地址在数据库中的列索引
		int fileColumn=cursor.getColumnIndexOrThrow(Media.DATA);
		//获取图片标题在数据库中的列索引
		int titleColumn=cursor.getColumnIndexOrThrow(Media.TITLE);
		//获取图片名字在数据库中的列索引
		int displayColumn=cursor.getColumnIndexOrThrow(Media.DISPLAY_NAME);
		//遍历游标,获取图片信息
		while(cursor.moveToNext()){
			String imgUrl=cursor.getString(fileColumn);//图片地址
			String imgTitle=cursor.getString(titleColumn);//图片标题
			String imgName=cursor.getString(displayColumn);//图片名称
			Log.i("图片", imgTitle+"/n"+imgName+"/n"+imgUrl);
			imgUrls.add(imgUrl);//将图片地址存储到集合
		}
		imgNumTv.setText("你有"+imgUrls.size()+"张图片");
		//设置适配器
		gallery.setAdapter(new ImageAdapter(imgUrls,this));
		//设置项点击事件
		gallery.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				try {
					//获取图片EXIF信息
					ExifInterface ei=new ExifInterface(imgUrls.get(position));
					String description=ei.getAttribute(ExifInterface.TAG_MODEL);
					Toast.makeText(MainActivity.this, description, 0).show();
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		});
		
	}

}
</span>
画廊适配器代码
<span style="font-size:14px;">package com.example.photoalbumdemo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

public class ImageAdapter extends BaseAdapter{
	//图片地址集合
	private List<String> imgUrls=new ArrayList<>();
	private Context context;
	private int screenWidth;//屏幕宽
	private int screenHeight;//屏幕高
	public ImageAdapter(List<String> imgUrls,Context context) {
		this.imgUrls=imgUrls;
		this.context=context;
		//获取屏幕宽高
		WindowManager manager=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		screenWidth=manager.getDefaultDisplay().getWidth();
		screenHeight=manager.getDefaultDisplay().getHeight();
	}
	@Override
	public int getCount() {
		return imgUrls.size();
	}

	@Override
	public Object getItem(int position) {
		return imgUrls.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		try {
			//修改图片EXIF数据信息
			ExifInterface ei=new ExifInterface(imgUrls.get(position));
			ei.setAttribute(ExifInterface.TAG_MODEL, "2015");
			ei.saveAttributes();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		ViewHolder holder=null;
		if(convertView==null){
			ImageView imageView=new ImageView(context);
			convertView=imageView;
			holder=new ViewHolder();
			holder.imageView=imageView;
			convertView.setTag(holder);
		}else{
			holder=(ViewHolder) convertView.getTag();			
		}
		//压缩图片
		BitmapFactory.Options options=new BitmapFactory.Options();
		options.inJustDecodeBounds=true;
		BitmapFactory.decodeFile(imgUrls.get(position), options);
		//获取图片宽高
		int imgWidth=options.outWidth;
		int imgHeight=options.outHeight;
		//求出采样比率
		int radio=imgWidth/screenWidth>imgHeight/screenHeight?imgWidth/screenWidth:imgHeight/screenHeight;
		options.inJustDecodeBounds=false;
		options.inSampleSize=radio;
		Bitmap bitmap=BitmapFactory.decodeFile(imgUrls.get(position), options);
		//图片显示
		holder.imageView.setImageBitmap(bitmap);
		return convertView;
	}
	class ViewHolder{
		ImageView imageView;
	}
}
</span>
注意要在配置文件中添加写权限,不然修改图片EXIF信息不成功
<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.photoalbumdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.photoalbumdemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
</span>




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值