近期在做Android的项目,当中部分涉及到图像处理的内容.这里先讲述怎样调用Camera应用程序进行拍照,并截图和保存显示在ImageView控件中以及遇到的困难和解决方法.

    PS:作者购买了本《Android第一行代码 著:郭霖》,參照里面的内容完毕(推荐该书,前面的布局及应用很不错).网上这类资料许多,作者只分享给刚開始学习的人同一时候在线记录些内容,希望对大家有所帮助.

   首先,设置activity_main.xml为LinearLayout布局且 android:orientation="vertical"

<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TakePhoto Button" /> <ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />

   然后,在MainActivity.java文件中public class MainActivity extends Activity改动源码.加入自己定义变量:

//自己定义变量
public static final int TAKE_PHOTO = 1;
public static final int CROP_PHOTO = 2;
private Button takePhotoBn;
private ImageView showImage;
private Uri imageUri; //图片路径
private String filename; //图片名称

   加入函数实现点击拍照功能:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takePhotoBn = (Button) findViewById(R.id.button1);
showImage = (ImageView) findViewById(R.id.imageView1);
//点击"Photo Button"button照相
takePhotoBn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//图片名称 时间命名
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
Date date = new Date(System.currentTimeMillis());
filename = format.format(date);
//创建File对象用于存储拍照的图片 SD卡根文件夹
//File outputImage = new File(Environment.getExternalStorageDirectory(),"test.jpg");
//存储至DCIM目录
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File outputImage = new File(path,filename+".jpg");
try {
if(outputImage.exists()) {
outputImage.delete();
}
outputImage.createNewFile();
} catch(IOException e) {
e.printStackTrace();
}
//将File对象转换为Uri并启动照相程序
imageUri = Uri.fromFile(outputImage);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //照相
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); //指定图片输出地址
startActivityForResult(intent,TAKE_PHOTO); //启动照相
//拍完照startActivityForResult() 结果返回onActivityResult()函数
}
}); if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}

   通过startActivityForResult和onActivityResult方法实现拍照截图和保存功能:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) {
Toast.makeText(MainActivity.this, "ActivityResult resultCode error", Toast.LENGTH_SHORT).show();
return;
}
switch(requestCode) {
case TAKE_PHOTO:
Intent intent = new Intent("com.android.camera.action.CROP"); //剪裁
intent.setDataAndType(imageUri, "image/*");
intent.putExtra("scale", true);
//设置宽高比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
//设置裁剪图片宽高
intent.putExtra("outputX", 340);
intent.putExtra("outputY", 340);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
Toast.makeText(MainActivity.this, "剪裁图片", Toast.LENGTH_SHORT).show();
//广播刷新相冊
Intent intentBc = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intentBc.setData(imageUri);
this.sendBroadcast(intentBc);
startActivityForResult(intent, CROP_PHOTO); //设置裁剪參数显示图片至ImageView
break;
case CROP_PHOTO:
try {
//图片解析成Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(
getContentResolver().openInputStream(imageUri));
Toast.makeText(MainActivity.this, imageUri.toString(), Toast.LENGTH_SHORT).show();
showImage.setImageBitmap(bitmap); //将剪裁后照片显示出来
} catch(FileNotFoundException e) {
e.printStackTrace();
}
break;
default:
break;
}
}

   
因为涉及到SD卡中写数据操作和Camera操作,须要在AndroidMainfest.xml文件里声明权限:

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

执行结果例如以下图所看到的:

       

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRWFzdG1vdW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="180" height="340">

    须要注意下面几个问题:

    1.拍照和截图都涉及到startActivityForResult和onActivityResult的交互操作.

startActivityForResult(
Intent intent, //Intent对象
int requestCode //>=0 当Activity结束时requestCode将归还在onActivityResult()中
)
onActivityResult(
int requestCode, //提供给onActivityResult,以确认返回的数据是从哪个Activity返回的
int resultCode, //由子Activity通过其setResult()方法返回 通常为RESULT_CANCELED或RESULT_OK
Intent data //一个Intent对象,带有返回的数据
)

当中onActivityResult的requestCode和startActivityForResult中的requestCode相相应.同一时候结合Intent意图实现拍照和截图,核心代码例如以下:(intent的參数设置省略)

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

    startActivityForResult(intent,TAKE_PHOTO);

    Intent intent = new Intent("com.android.camera.action.CROP"); 

    startActivityForResult(intent, CROP_PHOTO);

    2.使用Android拍照保存在系统相冊,图库不能立马显示最新照片.解决方法是发送系统内置的广播去刷新相冊实现显示.代码例如以下:

Intent intentBc = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intentBc.setData(imageUri);
this.sendBroadcast(intentBc);

    可能你会使用以下这条广播扫描整个SD卡,但4.4已禁止这种操作:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse(...)))

    參考资料 http://blog.csdn.net/xiaanming/article/details/8990627

    3.当执行程序是可能会发现结果图像显示非常小,当通过一个Intent意图触发时,Camera程序不会将全尺寸图像返回给主调活动,这样须要大量的内存,而移动设备内存会有一定限制.通常Camera将在返回的意图中返回一幅非常小的缩略图,大图可能会导致OOM问题.參考:《Android多媒体开发高级编程 著:Shawn Van Every》

    针对大图像Android提供BitmapFactory类,同意通过各种资源载入Bitmap图像.调用BitmapFactory.Options类能够定义怎样将Bitmap读入内存,当载入图像时,可设置BitmapFactory採样大小.并指定inSampleSize參数表明载入时结果Bitmap图像所占的比例.如inSampleSize=8表明产生一副大小为原始图像1/8的图像.參考以下代码:

if(resultCode==RESULT_OK) {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels; //宽度
int height = dm.heightPixels ; //高度
//载入图像尺寸而不是图像本身
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true; //bitmap为null 仅仅是把图片的宽高放在Options里
Bitmap bitmap = BitmapFactory.decodeFile(imageUri.toString(), bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
//设置图片压缩比例 假设两个比例大于1 图像一边将大于屏幕
if(heightRatio>1&&widthRatio>1) {
if(heightRatio>widthRatio) {
bmpFactoryOptions.inSampleSize = heightRatio;
}
else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
//图像真正解码
bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(imageUri.toString(), bmpFactoryOptions);
showImage.setImageBitmap(bitmap); //将剪裁后照片显示出来
}

    4.使用nexus 4 剪裁图片后不能setImageBitmap显示在ImageView控件中,当中仅仅有保存button,没有剪裁button.測试发现没有返回RESULT_OK.这个问题不能解决.Why?

參考:Unable to Save Photo Edits

    最后希望文章对大家有所帮助,这是我学习Android图像处理部分的基础性文章与解决过程.下载地址:
http://download.csdn.net/detail/eastmount/8074833

參考资料和推荐博文:(都是很不错的资料-.-)

    《Android第一行代码》著郭霖 參考8.3 调用摄像头和相冊

    android拍照图片选取与图片剪裁 By:Lee_Allen 

    Android_照相机Camera_调用系统照相机返回data为空 By:strawberry2013    Android图片剪裁功能实心具体解释
By:小马


    Android开发 拍照、图片集保存照片技巧

    Android 拍照并显示在ImageView中(进阶)
By:leesa


    android调动系统的照相机并把照片显示在ImageView上

    cameraintent
data null in onActivityResult(int requestCode, int resultCode, Intentdata)


    Android高效载入大图、多图解决方式,有效避免程序OOM By:guolin

    Android相机、相冊获取图片显示并保存到SD卡
By:唐韧_Ryan


    android、获取本地图片|直接获取照相图片
By:zcljy0318


(By:Eastmount 2014-10-23 晚10点
http://blog.csdn.net/eastmount/)

[Android] 拍照、截图、保存并显示在ImageView控件中的更多相关文章

  1. Android调用相机拍摄照片并显示到 ImageView控件中

    在前面的一篇文章中曾介绍过简单的开启相机照相功能,详见 Android简单调用相机Camera功能,实现打开照相功能 ,这一次就会将前面拍摄的照片显示到ImageView中,形成一个完整的效果 看实例 ...

  2. arrays.xml中使用integer-array引用drawable图片资源,代码中如何将这些图片资源赋值到ImageView控件中

    当我们在arrays.xml文件中声明一些图片资源数组的时候: <?xml version="1.0" encoding="utf-8"?> < ...

  3. Android开发:在布局里移动ImageView控件

    在做一个app时碰到需要移动一个图案的位置,查了一上午资料都没找到demo,自己写一个吧 RelativeLayout.LayoutParams lp = new RelativeLayout.Lay ...

  4. Android控件之ImageView(显示图片的控件)

    一.ImageView属性: android:src = "@drawable/ic_launcher"——ImageView的内容图像(可以和android:background ...

  5. Android开发ImageView控件缩放图片

    首先还是最基础的ImageView控件如何显示图片: <ImageView                Android:id="@+id/imgView"          ...

  6. 从网络中获取图片显示到Image控件并保存到磁盘

    一.从网络中获取图片信息: /// <summary> /// 获取图片 /// </summary> /// <param name="url"&g ...

  7. Android天坑ImageView控件上下留白原因与解决

    ImageView控件上下留白 如下,误以为是padding的问题.搜索无果 后来发现是需要添加android:adjustViewBounds="true",调整ImageVie ...

  8. android中动态修改ImageView控件的宽高度

    本例实现了动态修改ImageView控件的宽高度,有两个按钮,一个按钮实现放大image,一个按钮实现缩小image activity_main.xml <?xml version=" ...

  9. Android开发技巧——定制仿微信图片裁剪控件

    拍照--裁剪,或者是选择图片--裁剪,是我们设置头像或上传图片时经常需要的一组操作.上篇讲了Camera的使用,这篇讲一下我对图片裁剪的实现. 背景 下面的需求都来自产品. 裁剪图片要像微信那样,拖动 ...

随机推荐

  1. SQL SERVER 2012 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 (System.Data)

    标题: 连接到服务器------------------------------ 无法连接到 192.168.1.253. ------------------------------其他信息: 尝试 ...

  2. 在Mac OSX 上配置Appium+Android自动化测试环境

    前提准备 开始正文之前,你需要准备好一些基本条件: 安装好Mac OSX 操作系统的设备 能够访问中国局域网以外资源的方法(没有也行,但很痛苦) 已经安装好 homebrew 已经安装好 Python ...

  3. 获取本机IP,用户代理

    1.获取本机IP:http://httpbin.org/ip 2.获取用户代理 https://httpbin.org/user-agent https://httpbin.org/ httpbin( ...

  4. zabbix通过snmp监控windows主机

    1.开启Windows的snmp功能 2.配置snmp服务 设置snmp服务社区名称及允许的主机,设置完成后重启snmp服务 3.在zabbix server上测试 测试需要使用命令snmpwalk, ...

  5. Java模式的秘密--java常用的几种模式

    要学习设计模式,首先要明白设计模式,就是为实现某一种或某一组功能提供的代码编码方式.它没有固定的套路,只有约定俗成的风格.所有编码者可以根据已有的设计模式开放思维,设计出自己的设计模式,也会在无意中使 ...

  6. 系统重装 如何在PC上安装Mac OS,苹果操作系统

    [苹果系统 无影精品]<精睿 无影技术Mac OS X 中文优化正式会员版V10.14和V10.16>◆ 系统前沿:==================================== ...

  7. 【C#】.NET提供了哪些类型来实现反射

    实现反射的类型大多数都定义在System.Reflection命名空间之下. Assembly 定义一个Assembly,它是可重用.无版本冲突并且可自我描述的公共语言运行库应用程序构造块. Asse ...

  8. 关于Laravel5.2在php5.3.6X和在php7.1.10下的内存溢出

    php5.3.6X是编译安装,在debug模式下,频繁报出内存泄露警告 php7.1.10下则不会有此错误. 顺便提下:测试发现ThinkPHP也不会有该内存泄露警告! 希望知道如何解决该问题的童鞋能 ...

  9. ZAP介绍

    Zed Attack Proxy简写为ZAP,是一个简单易用的渗透测试工具,是发现Web应用中的漏洞的利器,更是渗透测试爱好者的好东西.ZAP下载地址:https://www.owasp.org/in ...

  10. mac 下 pycharm 快捷键

    用过快捷键立即感觉高大上了,最主要的是很方便啊!很强大 cmd b 跳转到声明处(cmd加鼠标) opt + 空格 显示符号代码 (esc退出窗口 回车进入代码) cmd []光标之前/后的位置 op ...