Android入门--实现选择并编辑图片设置成头像

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android入门--实现选择并编辑图片设置成头像相关的知识,希望对你有一定的参考价值。

在很多时候需要更换头像或者选择图片,所以这里总结下实现选择并编辑图片然后设置成头像的方法,下面开始: 
整体结构如下: 
技术分享

创建项目,命名为ChooseImage_test

创建完成,在drawable-hdip文件夹中添加一张默认头像图片,用于在用户选择头像之前显示或者当用户未选择头像时做默认头像: 
技术分享

创建布局文件

这里为了贴合实际,整个页面就只有一个ImageView,当然现在是矩形的ImageView显示头像,后面会结合设置圆形头像的功能实现圆形头像选择功能

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="110dp"
        android:background="@drawable/default_icon" />

</RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在MainActivity.java中进行主要逻辑编写

初始化ImageView组件

public class MainActivity extends Activity {

    private ImageView iv_icon = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv_icon = (ImageView) findViewById(R.id.iv_icon);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

设置ImageView的点击事件

这里的点击事件为:当点击头像弹出一个对话框,让用户选择是使用本地图库的图片作为头像还是使用拍照作为头像

    iv_icon.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

            }
        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

弹出对话框

这里将弹出提示框封装成了一个chooseDialog()方法

private void chooseDialog() {
        new AlertDialog.Builder(this)//
                .setTitle("选择头像")//

                .setNegativeButton("相册", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })

                .setPositiveButton("拍照", new DialogInterface.OnClickListener() {                
                    @Override
                    public void onClick(DialogInterface dialog, int which) {


                    }
                }).show();

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

创建工具类ImageUtils.java

在工具类中主要实现通过不同方式(拍照或相册)进行图片获取并进行剪裁图片和保存图片的功能

申明变量和构造方法

    public final static int ACTIVITY_RESULT_CAMERA = 0001;//选择 拍照 的返回码
    public final static int ACTIVITY_RESULT_ALBUM = 0002;//选择 相册 的返回码

    public Uri photoUri;// 图片路径的URI
    private Uri tempUri;

    private File picFile;// 图片文件

    private Context context;

    // 构造方法
    public ImageUtils(Context context) {
        super();
        this.context = context;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

创建方法byCamera()用于选择拍照的方式

主要步骤已在代码中写明,这里就不再赘述

// 选择拍照的方式
    public void byCamera() {
        try {
            // 创建文件夹
            File uploadFileDir = new File(
                    Environment.getExternalStorageDirectory(), "/icon");

            if (!uploadFileDir.exists()) {
                uploadFileDir.mkdirs();
            }
            // 创建图片,以当前系统时间命名
            picFile = new File(uploadFileDir,
                    SystemClock.currentThreadTimeMillis() + ".png");
            if (!picFile.exists()) {
                picFile.createNewFile();
            }
            // 获取到图片路径
            tempUri = Uri.fromFile(picFile);

            // 启动Camera的Intent,传入图片路径作为存储路径
            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
            //启动Intent
            ((MainActivity) context).startActivityForResult(cameraIntent,
                    ACTIVITY_RESULT_CAMERA);

            System.out.println("-->tempUri : " + tempUri.toString()
                    + "-->path:" + tempUri.getPath());
        } catch (ActivityNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

创建方法byAlbum()用于选择相册的方式

如上,主要步骤已在代码中写明,这里就不再赘述

// 选择相册的方式
    public void byAlbum() {
        try {
            // 创建文件夹
            File pictureFileDir = new File(
                    Environment.getExternalStorageDirectory(), "/icon");
            if (!pictureFileDir.exists()) {
                pictureFileDir.mkdirs();
            }
            // 创建图片,以当前系统时间命名
            picFile = new File(pictureFileDir,
                    SystemClock.currentThreadTimeMillis() + ".png");
            if (!picFile.exists()) {
                picFile.createNewFile();
            }
            // 获取到图片路径
            tempUri = Uri.fromFile(picFile);

            // 获得剪辑图片的Intent
            final Intent intent = cutImageByAlbumIntent();
            ((MainActivity) context).startActivityForResult(intent,
                    ACTIVITY_RESULT_ALBUM);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

创建方法cutImageByAlbum()用于返回一个调用系统剪辑图片的Intent

具体参数设置就不再赘述

    // 调用图片剪辑程序的Intent
    private Intent cutImageByAlbumIntent() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
        intent.setType("image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 100);
        intent.putExtra("outputY", 100);
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        return intent;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

创建方法cutImageByCamera()用于通过拍照后调用图片剪辑

    //通过相机拍照后进行剪辑
    public void cutImageByCamera() {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(tempUri, "image/*");
        intent.putExtra("crop", "true");
        //设定宽高比
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        //设定剪裁图片宽高
        intent.putExtra("outputX", 100);
        intent.putExtra("outputY", 100);
        intent.putExtra("scale", true);

        intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
        intent.putExtra("return-data", false);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true); 
        ((MainActivity) context).startActivityForResult(intent,
                ACTIVITY_RESULT_ALBUM);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

创建方法decodeBitmap()方法将文件编码成Bitmap

    // 对图片进行编码成Bitmap
    public Bitmap decodeBitmap() {
        Bitmap bitmap = null;
        try {
            if (tempUri != null) {
                photoUri = tempUri;
                bitmap = BitmapFactory.decodeStream(context
                        .getContentResolver().openInputStream(photoUri));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        return bitmap;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在对话框的点击按钮中添加事件

“相册”的点击事件

    .setNegativeButton("相册", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.dismiss();
                        imageUtils.byAlbum();

                    }
                })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

“拍照”的点击事件

.setPositiveButton("拍照", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.dismiss();
                        String status = Environment.getExternalStorageState();
                        if (status.equals(Environment.MEDIA_MOUNTED)) {//判断是否存在SD卡
                            imageUtils.byCamera();
                        }
                    }
                })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在mainActivity.java中重写onActivityResult()方法用于根据传回的参数进行相关设定

// 这里需要注意resultCode,正常情况返回值为 -1 没有任何操作直接后退则返回 0
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        System.out.println("-->requestCode:" + requestCode + "-->resultCode:"
                + resultCode);

        switch (requestCode) {
        case ImageUtils.ACTIVITY_RESULT_CAMERA: // 拍照
            try {
                if (resultCode == -1) {
                    imageUtils.cutImageByCamera();
                } else {
                    // 因为在无任何操作返回时,系统依然会创建一个文件,这里就是删除那个产生的文件
                    if (imageUtils.picFile != null) {
                        imageUtils.picFile.delete();
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        case ImageUtils.ACTIVITY_RESULT_ALBUM:
            try {
                if (resultCode == -1) {
                    Bitmap bm_icon = imageUtils.decodeBitmap();
                    if (bm_icon != null) {
                        iv_icon.setImageBitmap(bm_icon);
                    }
                } else {
                    // 因为在无任何操作返回时,系统依然会创建一个文件,这里就是删除那个产生的文件
                    if (imageUtils.picFile != null) {
                        imageUtils.picFile.delete();
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

以上,整个过程就完成了,运行效果图如下: 
技术分享 技术分享

技术分享 技术分享

选择图片作为头像的功能基本实现,附上完整源码:

MainActivity.Java

package com.example.chooseimage_test;

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

public class MainActivity extends Activity {

    private ImageView iv_icon = null;

    private ImageUtils imageUtils = null;

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

        iv_icon = (ImageView) findViewById(R.id.iv_icon);

        // 初始化工具类的实例
        imageUtils = new ImageUtils(this);

        iv_icon.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                chooseDialog();
            }
        });
    }

    private void chooseDialog() {
        new AlertDialog.Builder(this)//
                .setTitle("选择头像")//

                .setNegativeButton("相册", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.dismiss();
                        imageUtils.byAlbum();

                    }
                })

                .setPositiveButton("拍照", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.dismiss();
                        String status = Environment.getExternalStorageState();
                        if (status.equals(Environment.MEDIA_MOUNTED)) {// 判断是否存在SD卡
                            imageUtils.byCamera();
                        }
                    }
                }).show();

    }

    // 这里需要注意resultCode,正常情况返回值为 -1 没有任何操作直接后退则返回 0
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        System.out.println("-->requestCode:" + requestCode + "-->resultCode:"
                + resultCode);

        switch (requestCode) {
        case ImageUtils.ACTIVITY_RESULT_CAMERA: // 拍照
            try {
                if (resultCode == -1) {
                    imageUtils.cutImageByCamera();
                } else {
                    // 因为在无任何操作返回时,系统依然会创建一个文件,这里就是删除那个产生的文件
                    if (imageUtils.picFile != null) {
                        imageUtils.picFile.delete();
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        case ImageUtils.ACTIVITY_RESULT_ALBUM:
            try {
                if (resultCode == -1) {
                    Bitmap bm_icon = imageUtils.decodeBitmap();
                    if (bm_icon != null) {
                        iv_icon.setImageBitmap(bm_icon);
                    }
                } else {
                    // 因为在无任何操作返回时,系统依然会创建一个文件,这里就是删除那个产生的文件
                    if (imageUtils.picFile != null) {
                        imageUtils.picFile.delete();
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        }
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

ImageUtils.java

package com.example.chooseimage_test;

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

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.os.SystemClock;
import android.provider.MediaStore;

public class ImageUtils {

    public final static int ACTIVITY_RESULT_CAMERA = 0001;//选择 拍照 的返回码
    public final static int ACTIVITY_RESULT_ALBUM = 0002;//选择 相册 的返回码

    public Uri photoUri;// 图片路径的URI
    private Uri tempUri;

    public File picFile;// 图片文件

    private Context context;

    // 构造方法
    public ImageUtils(Context context) {
        super();
        this.context = context;
    }

    // 选择拍照的方式
    public void byCamera() {
        try {
            // 创建文件夹
            File uploadFileDir = new File(
                    Environment.getExternalStorageDirectory(), "/icon");

            if (!uploadFileDir.exists()) {
                uploadFileDir.mkdirs();
            }
            // 创建图片,以当前系统时间命名
            picFile = new File(uploadFileDir,
                    SystemClock.currentThreadTimeMillis() + ".png");
            if (!picFile.exists()) {
                picFile.createNewFile();
            }
            // 获取到图片路径
            tempUri = Uri.fromFile(picFile);

            // 启动Camera的Intent,传入图片路径作为存储路径
            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
            //启动Intent
            ((MainActivity) context).startActivityForResult(cameraIntent,
                    ACTIVITY_RESULT_CAMERA);

            System.out.println("-->tempUri : " + tempUri.toString()
                    + "-->path:" + tempUri.getPath());
        } catch (ActivityNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 选择相册的方式
    public void byAlbum() {
        try {
            // 创建文件夹
            File pictureFileDir = new File(
                    Environment.getExternalStorageDirectory(), "/icon");
            if (!pictureFileDir.exists()) {
                pictureFileDir.mkdirs();
            }
            // 创建图片,以当前系统时间命名
            picFile = new File(pictureFileDir,
                    SystemClock.currentThreadTimeMillis() + ".png");
            if (!picFile.exists()) {
                picFile.createNewFile();
            }
            // 获取到图片路径
            tempUri = Uri.fromFile(picFile);

            // 获得剪辑图片的Intent
            final Intent intent = cutImageByAlbumIntent();
            ((MainActivity) context).startActivityForResult(intent,
                    ACTIVITY_RESULT_ALBUM);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 调用图片剪辑程序的Intent
    private Intent cutImageByAlbumIntent() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
        intent.setType("image/*");
        intent.putExtra("crop", "true");
        //设定宽高比
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        //设定剪裁图片宽高
        intent.putExtra("outputX", 200);
        intent.putExtra("outputY", 200);

        intent.putExtra("noFaceDetection", true);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        return intent;
    }

    //通过相机拍照后进行剪辑
    public void cutImageByCamera() {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(tempUri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 100);
        intent.putExtra("outputY", 100);
        intent.putExtra("scale", true);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
        intent.putExtra("return-data", false);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        ((MainActivity) context).startActivityForResult(intent,
                ACTIVITY_RESULT_ALBUM);
    }

    // 对图片进行编码成Bitmap
    public Bitmap decodeBitmap() {
        Bitmap bitmap = null;
        try {
            if (tempUri != null) {
                photoUri = tempUri;
                bitmap = BitmapFactory.decodeStream(context
                        .getContentResolver().openInputStream(photoUri));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        return bitmap;
    }
}

到此,基本完成选择头像的功能,下一篇文章将总结做成圆形头像的方法。





以上是关于Android入门--实现选择并编辑图片设置成头像的主要内容,如果未能解决你的问题,请参考以下文章

Android之修改用户头像并上传服务器(实现手机拍照和SD卡选择上传)

自定义控件 编辑和选取圆形头像

Android实战简易教程-第二十八枪(基于Bmob实现头像图片设置和网络上传功能!)

Android开发之用户头像上传

Android中通过访问本地相册或者相机设置用户头像

如何选择一张图片来设置头像