Android开发中,怎样调用摄像机拍照以及怎样从本地图库中选取照片

Android开发中,怎样调用摄像机拍照以及怎样从本地图库中选取照片这是属于我的第一篇博文,首先说明一下,文章属性为原创,其实不能说是原创,我是在学习的过程中根据自己的理解整理的。文章内容大多为书本上的内容,书本是郭霖的《第一行代码》。    正文:现在很多应用程序会调用摄像头的拍照功能,比如哪个程序要上传一张图片作为用户头像,这是启用摄像头拍照会很方便。当然,还有第二种方法,就是在本地图库选取已经被保存的图片。现在,我就根据自己学习的过程,将这部分

大家好,又见面了,我是你们的朋友全栈君。

这是属于我的第一篇博文,首先说明一下,文章属性为原创,其实不能说是原创,我是在学习的过程中根据自己的理解整理的。文章内容大多为书本上的内容,书本是郭霖的《第一行代码》。

       正文:现在很多应用程序会调用摄像头的拍照功能,比如哪个程序要上传一张图片作为用户头像,这是启用摄像头拍照会很方便。当然,还有第二种方法,就是在本地图库选取已经被保存的图片。现在,我就根据自己学习的过程,将这部分只是进行整理,如下:



public class MainActivity extends AppCompatActivity {
    private Button button;
    private ImageView imageView;
    private Uri imageuri;
    private Button choose;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        button = (Button) findViewById(R.id.button);
        imageView = (ImageView) findViewById(R.id.imageView);
        choose = (Button) findViewById(R.id.button2);
        
        //此按钮事件是拍照,启动摄像机的功能
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //创建一个File对象,用于存储接下来照相机拍摄的照片
                File file = new File(Environment.getExternalStorageDirectory(), "output_image.jpg");
                if (file.exists()) {
                    file.delete();
                }
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                imageuri = Uri.fromFile(file);
                //下面这个intent对象就是用于启动照相机的
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageuri);//指定图片的输出地址
                startActivityForResult(intent, 1);//启动照相机,这里传入的参数1,其实只要是固定一个值都行,
                                                  //比较好的做法是声明一个全局常量比较好,我在这里没有这么做。
            }
        });
        //此按钮事件是选取本地图片,启动相册
        choose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("android.intent.action.GET_CONTENT");//这个intent对象是用于开启本地图库的
                intent.setType("image/*");//给intent对象设置必要的参数
                startActivityForResult(intent, 3);//开启本地图库
            }
        });
       
    }

    @Override
    //因为我们用startActivityForResult方法启动活动,所有它们处理完结果后,会回调上一个活动的onActivityResult方法,这里我们就在MainActivity重写此方法
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case 1://就是照相机拍好了照片来回调的这个方法的case 1,这个时候我们想要启动照片的裁剪程序
                if (resultCode == RESULT_OK) {
                    Intent intent = new Intent("com.android.camera.action.CROP");//这个intent对象启动裁剪程序
                    intent.putExtra("scale", true);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageuri);//设置图片的输出地址
                    intent.setDataAndType(imageuri, "image/*");//设置图片的返回格式
                    startActivityForResult(intent, 2);
                }
                break;
            case 2://裁剪好了的图片回调此方法的case 2,这个时候我们就要将裁剪好的图片设置到imageview里
                if (resultCode == RESULT_OK) {
                    try {
               
                        //BitmapFactory的decodeStream()方法将照片解析成Bitmap对象
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageuri));
                        imageView.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case 3://本地图库选取图片后,回调此方法的case 3,在这里我们主要做的就是图片的处理工作
                if (resultCode == RESULT_OK) {
                    //判断系统版本号,如果API>19,即Android 4.4版本以上用这个方法处理图片
                    if (Build.VERSION.SDK_INT >= 19) {
                        handleImageOnKitKat(data);
                    }
                    else {
                        //android4.4以下,用这个方法处理图片
                        handleImageBeforeKitKat(data);
                    }
                }
                break;
            default:
                break;
        }

    }


    @TargetApi(19)
    private void handleImageOnKitKat(Intent data) {
        //其实这个方法的目标很简单,就是要获取图片的真实路径imagepath,然后我们会再提供一个方法将imagepath作为参数来显示图片
        String imagepath = null;
        //android4.4以上的版本,我们获取的图片uri不是真实的图片uri,是封装过的,不能直接用来显示图片,我们要进行解析
        Uri uri = data.getData();//通过传入intent参数来获取信息,图片的内容uri

        //接下来的内容看似复杂,其实很简单,我们进行了很多判断,首先判断这个uri是否为document类型,
        //如果是document类型的话,就取出document id处理,如果不是,就普通方式处理
        //另外,我们又对uri的权限部分进行判断,如果是media格式,则document id还要再次进行解析
        if (DocumentsContract.isDocumentUri(this, uri))//判断如果是document类型,则通过document id处理
        {
            String docId = DocumentsContract.getDocumentId(uri);//通过uri获取document id。
            //判断我们的uri的权限部分,media格式,对document id用":"分割,取出真正的数字id
            if ("com.android.provider.media.documents".equals(uri.getAuthority())) {
                //split方法返回的结果是一个数组,我们选取第二个,即角标为1,这样我们就解析出数字格式的id
                String id = docId.split(":")[1];
                String selection = MediaStore.Images.Media._ID + "=" + id;//用id构建新的条件语句,并且在后面query()方法
                                                                          //进行数据库查询是作为参数,主要是约束我们的查询条件
                //getImagepath()方法是我们自己提供的用来获取图片真实路径
                imagepath = getImagepath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
                
            } else if ("com.android.provider.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("conten://downloads/public_downloads"), Long.valueOf(docId));
                imagepath = getImagepath(contentUri, null);
                
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            //如果不是document类型的uri,则使用普通方法处理
            imagepath = getImagepath(uri, null);
            
        }
        displayImage(imagepath);//最后,我们根据路径显示图片
    }

    private void handleImageBeforeKitKat(Intent data)
    {
        Uri uri=data.getData();
        String imagepath=getImagepath(uri,null);
        displayImage(imagepath);
        
    }

    //获取图片路径的方法
    private String getImagepath(Uri uri, String selection) {
        String path = null;
        //通过uri和selection获取真实的图片路径
        //其实selection就是一个约束条件,让我们指定查询哪一行,就好比name=lee,age=18这样
        Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToNext()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        
        return path;
    }
    //显示图片的方法
    private void displayImage(String imagepath)
    {
        if (imagepath!=null)
        {
            //BitmapFactory的decodeFile解析路径,使图片为Bitmap对象
            Bitmap bitmap=BitmapFactory.decodeFile(imagepath);
            imageView.setImageBitmap(bitmap);
        }else {
            Toast.makeText(this,"图片获取失败",Toast.LENGTH_SHORT).show();
        }
    }


Android开发中,怎样调用摄像机拍照以及怎样从本地图库中选取照片

        其实,很多照片即使裁剪了以后体积还是很大,直接加载到内存,很容易使程序崩溃。更好的做法是根据项目需求对照片进行适当的压缩,然后加载到内存。这个时候就要考验我们的阅读文档能力啦,学无止境啊。



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/162735.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Ant笔记(一)Ant下载与安装

    Ant笔记(一)Ant下载与安装此系列参考官方文档http://ant.apache.org/manual/index.htmlAnt是什么ApacheAnt是一个java为基础的构建工具,它跨平台,使用清晰,功能强大。

  • Java IO编程

    Java IO编程JavaIOJavaNIO详解(一)JavaNIO详解(二)本列表会不断更新

  • 牛客网–2的幂次方

    牛客网–2的幂次方

  • unity htc vive使用

    unity htc vive使用

  • VB程序设计教程(第四版) 龚沛曾

    VB程序设计教程(第四版) 龚沛曾VB程序设计教程(第四版)龚沛曾课后习题答案目录第一章课后答案第二章课后答案第三章课后答案第四章课后答案第五章课后答案第六章课后答案第七章课后答案第八章课后答案….第一章课后答案1、简述VisualBasic的特点。答:(1)具有基于对象的可视化设计工具(2)事件驱动的编程机制(3)提供易学易用的应用程序集成开发环境(4…

  • .apk反编译_apk反编译教程

    .apk反编译_apk反编译教程原文作者:[color=blue][b]lpohvbe[/b][/color]原文地址:[url]http://blog.csdn.net/lpohvbe/article/details/7981386[/url]本人接触不久,有错误望请各位神牛不吝赐教,仅仅希望把自己这段时间研究的东西分享一下,如果可以帮助到有需要的童鞋万感荣幸。欢迎评论转载,但请加上转载来源谢谢!请尊重开发者劳动成果!…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号