Android Use Camera 之捕捉图像并修改图像属性

git clone https://github.com/lnmcc/CameraExample.git

下面的例子将展示如何通过Camera Intent捕捉图像并修改图像属性的方法。

activity_main.xml

alt none

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

	<ImageView
	    android:id="@+id/imgView"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content" />

	<TextView
	    android:id="@+id/TitleTV"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:text="Title" />

	<EditText
            android:id="@+id/TitleET"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content" />

	<TextView 
            android:id="@+id/DescriptionTV"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:text="Description" />

	<EditText
            android:id="@+id/DescriptionET" 
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content" />

	<Button
	    android:id="@+id/TakePictureBT"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:text="Take Picture" />

	<Button
	    android:id="@+id/SaveDataBT"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:text="Save Data" />

</LinearLayout>

MainActivity.java

public class MainActivity extends Activity  {

        //标记一个Request,后面onActivityResult将检查这个标记来确认是由本activity发出的request
        static final int CAMERA_REQUEST = 1; 
        static final String TAG = "MainActivity";

	Uri imageFileUri;
	ImageView imgView;
	Button takePictureBT;
	Button saveDataBT;
	TextView titleTV;
	TextView descriptionTV;
	EditText titleET;
	EditText descriptionET;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		imgView = (ImageView)findViewById(R.id.imgView);
		takePictureBT = (Button)findViewById(R.id.TakePictureBT);
		saveDataBT = (Button)findViewById(R.id.SaveDataBT);
		titleTV = (TextView)findViewById(R.id.TitleTV);
		descriptionTV  = (TextView)findViewById(R.id.DescriptionTV);
		titleET = (EditText)findViewById(R.id.TitleET);
		descriptionET = (EditText)findViewById(R.id.DescriptionET);

		//View.GONE跟*View.INVISIBLE的区别在于前者隐藏控件并且不占用布局空间
		imgView.setVisibility(View.GONE);
		saveDataBT.setVisibility(View.GONE);
		titleTV.setVisibility(View.GONE);
		descriptionTV.setVisibility(View.GONE);
		titleET.setVisibility(View.GONE);
		descriptionET.setVisibility(View.GONE);

		takePictureBT.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View arg0) {
                                //获取内容提供器,并插入一个空图像,这里还传入了一个空的图像属性ContentValues以方 
                                //便后面我们手动更改图像属性。insert()将返回图像的uri。                       
				imageFileUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
                                //通过Intent调用系统Camera应用。
				Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
				i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
				startActivityForResult(i, CAMERA_REQUEST);
			}
		});

		//当点击saveData按钮后,读取TextView中的信息并更新到图像属性中。
		saveDataBT.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				ContentValues contentValues = new ContentValues(3);
                                //修改图像名称
				contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, titleET.getText().toString());
                                //修改图像描述
				contentValues.put(MediaStore.Images.Media.DESCRIPTION, descriptionET.getText().toString());
                                //通过内容提供器更新图像属性,返回被更新的行数。
				int upRows = getContentResolver().update(imageFileUri, contentValues, null, null);
				Toast.makeText(MainActivity.this, "Record Updated" + Integer.valueOf(upRows).toString(), Toast.LENGTH_SHORT).show();

				takePictureBT.setVisibility(View.VISIBLE);
				imgView.setVisibility(View.GONE);
				saveDataBT.setVisibility(View.GONE);
				titleTV.setVisibility(View.GONE);
				descriptionTV.setVisibility(View.GONE);
				titleET.setVisibility(View.GONE);
				descriptionET.setVisibility(View.GONE);
			}
		});
	}

        //startActivityForResult()调用Camera Intent,当Camera Intent完成任务后返回到MainActivity的时候会调用这个方法 
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

                //首先检查一下这个Camera Intent是否是由MainActivity请求的 
                //然后检查一下Camera Intent 是否执行成功                 
		if(requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
			takePictureBT.setVisibility(View.GONE);
			saveDataBT.setVisibility(View.VISIBLE);
			imgView.setVisibility(View.VISIBLE);
			titleTV.setVisibility(View.VISIBLE);
			descriptionTV.setVisibility(View.VISIBLE);
			descriptionET.setVisibility(View.VISIBLE);
			titleET.setVisibility(View.VISIBLE);

                        //图像的显示区域大小
			int dw = 200;
			int dh = 200;

			try {
				BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();

                                //inJustDecodeBound=true指示BitmapFactory只计算图像的大小,不要做真正的解码
				bmpFactoryOptions.inJustDecodeBounds = true;

				Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri),
						null, bmpFactoryOptions);

                                //计算实际图像和显示区域的缩放比率
				int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight / (float)dh);
				int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth / (float)dw);

				if(heightRatio > 1 && widthRatio > 1) {
					if(heightRatio > widthRatio) {

                                                //inSampleSize指示BitmapFactory对图像进行缩放
                                                //比如inSampleSize=2,则图片将被缩小到1/2
						bmpFactoryOptions.inSampleSize = heightRatio;
					} else {
						bmpFactoryOptions.inSampleSize = widthRatio;
					}
				}

                                //inJustDecodeBound=fase指示BitmapFactory开始真正的图像解码
				bmpFactoryOptions.inJustDecodeBounds = false;
				bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri),
						null, bmpFactoryOptions);

                                //在ImageView控件中显示图像
				imgView.setImageBitmap(bmp);
			} catch(FileNotFoundException e) {
				Log.v(TAG, e.toString());
			}
		}
	}
}

查看系统image数据库确认图像属性被更新

$ sqlite3 /data/data/com.android.providers.media/databases/external-ae126518.db
$ sqlite> . mode columns
$ sqlite> . header on
$ sqlite> select * from images;

返回数据:

139  /mnt/sdcard/DCIM/Camera/1380476346865.jpg  0  keyboard  image/jpeg  1380476346865                1380476346  1380476346     apple keyboard    1506676782  Camera

这里我把Title设置成keyboard,Description设置成apple keyboard

完成后的效果

alt none alt none alt none