Android Use Camera 之捕捉图像并修改图像属性
30 Sep 2013git clone https://github.com/lnmcc/CameraExample.git
下面的例子将展示如何通过Camera Intent捕捉图像并修改图像属性的方法。
activity_main.xml
<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
完成后的效果