Android头像上传 - Go语言中文社区

Android头像上传


内容概要

  • 实例演示和原理讲解
  • 从摄像头中获取图像
  • 从图库中获取图像
  • 在Android上对图像进行裁剪
  • 图像上传并在服务器保存图像

实例演示和原理讲解

头像上传流程

这里写图片描述

从摄像头中获取图像

本课时的主要内容如下:

  • 讲解Android客户端界面的设计与实现
  • 讲解如何调用摄像头拍摄一张照片
  • 讲解将摄像头拍摄的图像显示在界面上
public class MainActivity extends AppCompatActivity {
    private static int CAMERA_REQUEST_COOE = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //创建摄像头按钮的点击事件
        Button btn_camera = (Button) findViewById(R.id.btn_camera);
        btn_camera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(intent, CAMERA_REQUEST_COOE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAMERA_REQUEST_COOE) {
            //判断用户点击了拍照还是取消,如果是取消的话就不用进行数据的处理
            if (data == null) {
                return;
            } else {
                Bundle extras = data.getExtras();
                if (extras != null) {
                    //创建Bitmap用于保存用户拍照的数据
                    Bitmap bm = extras.getParcelable("data");
                    ImageView imageView = (ImageView) findViewById(R.id.imageView);
                    imageView.setImageBitmap(bm);
                }
            }
        }
    }
}

从图库中获取图像

本课时的主要内容如下:

  • 讲解调用系统图库并从图库中选取一张图片
  • 讲解如何将获取到的图片存储到SD卡中
//创建图像选择按钮的点击事件
Button btn_gallery = (Button) findViewById(R.id.btn_gallery);
        btn_gallery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("image/*");
                startActivityForResult(intent,GALLERY_REQUEST_COOE);
            }
        });

在上面的onActivityResult方法中添加以下判断代码:

else if(requestCode == GALLERY_REQUEST_CODE){
    if(data == null){
        return;
    }

    //当使用这种方法打开图库并选择一张照片后返回后onActivityResult方法中的data参数将会包含一个    
    //uri(就是选择图片所对应的uri统一资源标识符)

    Uri uri;
    uri = data.getData();//获取该uri

    //注:在Android中常用的uri有两种一种是以content开头的,另一种是以file开头的,那么从图库中获取的
    //uri到底是哪种类型的uri呢?

    Toast.makeText(MainActivity.this,uri.toString(),Toast.LENGTH_LONG).show();
    //content类型的,对于content类型的uri不能直接对他进行复制的操作

    Uri fileUri = convertUri(uri);//转换为file类型的uri

}
private Uri convertUri(Uri uri){
        InputStream is = null;
        try {
            is = getContentResolver().openInputStream(uri);
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            is.close();

            //将Bitmap类型转换为uri,将Bitmap中的数据写入到sdCard中的图像文件中,然后返回该图像的
            //uri,这样即实现将图片保存到sdcard中又实现了将content类型uri转换为file类型的uri
            return saveBitmap(bitmap);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    private Uri saveBitmap(Bitmap bm){
        //获取sdcard中的一个路径
        File tmpDir = new File(Environment.getExternalStorageDirectory()+"/avater");
        if(tmpDir.exists()){
            tmpDir.mkdir();
        }
        File img = new File(tmpDir.getAbsolutePath()+"avater.png");
        try {
            FileOutputStream fos = new FileOutputStream(img);

            //将图像的数据写入该输出流中,第一个参数是要压缩的格式,第二个参数:图片的质量
            bm.compress(Bitmap.CompressFormat.PNG,85,fos);

            fos.flush();
            fos.close();
            return Uri.fromFile(img);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

在Android上对图像进行裁剪

本课时的主要内容如下:

  • 讲解调用系统图像裁剪功能进行图像裁剪
  • 讲解两种Uri的转换
  • 讲解裁剪后的数据的处理

裁剪方法:

private void startImageZoom(Uri uri){
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri,"image/*");//通过参数uri将数据传递给裁剪界面
        intent.putExtra("crop","true");//设置在开启的intent中显示的view是可裁剪的
        intent.putExtra("aspectX",1);   //设置裁剪的宽高比例
        intent.putExtra("aspectY",1);
        intent.putExtra("outputX",150); //裁剪图片的宽高
        intent.putExtra("outputY",150);
        intent.putExtra("return-data",true);//裁剪之后的数据是通过intent返回回来的
        startActivityForResult(intent,CROP_REQUEST_CODE);
    }

该方法是在使用摄像头拍摄照片和从图库中选择照片后调用的,这里从新粘贴一下onActivityResult回调方法

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAMERA_REQUEST_CODE) {
            //判断用户点击了拍照还是取消,如果是取消的话就不用进行数据的处理
            if (data == null) {

                return;
            } else {
                Bundle extras = data.getExtras();
                if (extras != null) {
                    //创建Bitmap用于保存用户拍照的数据
                    Bitmap bm = extras.getParcelable("data");
                    /*ImageView imageView = (ImageView) findViewById(R.id.imageView);
                    imageView.setImageBitmap(bm);*/
                    Uri uri = saveBitmap(bm);
                    startImageZoom(uri);
                }
            }


        }
        else if(requestCode == GALLERY_REQUEST_CODE){
            if(data == null){
                return;
            }
            //当使用这种方法打开图库并选择一张照片后返回后onActivityResult方法中的data参数将会包含一个uri(就是选择图片所对应的uri统一资源标识符)
            Uri uri;
            uri = data.getData();//获取该uri,注:在Android中常用的uri有两种一种是以content开头的另一种是以file开头的,那么从图库中获取的uri到底是哪种类型的uri呢?
            //Toast.makeText(MainActivity.this,uri.toString(),Toast.LENGTH_LONG).show();//content类型的,对于content类型的uri不能直接对他进行复制的操作
            Uri fileUri = convertUri(uri);//转换为file类型的uri
            startImageZoom(fileUri);

        }
        //判断是否从图像裁剪界面返回
        else if (requestCode == CROP_REQUEST_CODE) {
            if (data == null) {
                //判断用户点击的是保存还是取消
                return;
            }
            Bundle extras = data.getExtras();
            Bitmap bm = extras.getParcelable("data");
            ImageView imageView = (ImageView) findViewById(R.id.imageView);
            imageView.setImageBitmap(bm);

        }

    }

图像上传并在服务器保存图像

本课时的主要内容如下:

  • 讲解AsyncHttpClient库的使用
  • 讲解Base64编码的编码与解码
  • 讲解在服务器上使用PHP保存文件

AsyncHttpClient 第三方开源类库
https://github.com/loopj/android-async-http/
他是针对android开发中发送http请求的
下载后将里面的jar包拷贝到项目的libs中然后右键Add As Library… (Android sutdio),这样就完成了这个库添加

添加一个新的方法用来发送图像数据

//添加一个新的方法用来发送图像数据
    //将Bitmap的数据发送到指定的服务器
    private void sendImage(Bitmap bm){
        //转换为byte数组类型
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG,60,stream);
        byte[] bytes = stream.toByteArray();

        //将这个数组编码成Base64编码的数据把他发送给服务器
        String img = new String(Base64.encodeToString(bytes,Base64.DEFAULT));
        //将string类型的数据发送到服务器在服务器端通过Base64解码得到图像的原始数据

        AsyncHttpClient client =  new AsyncHttpClient();
        RequestParams params = new RequestParams();//该对象用于保存要传输的参数

        params.add("img",img);

        client.post("http://192.168.56.1/ImgUpload.php", params, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int i, Header[] headers, byte[] bytes) {
                Toast.makeText(MainActivity.this, "Upload Success!", Toast.LENGTH_LONG).show();

            }

            @Override
            public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
                Toast.makeText(MainActivity.this, "Upload Fail!", Toast.LENGTH_LONG).show();
            }
        });
    }

在图像裁剪完之后调用这个方法,要访问网络还需要添加网络访问权限

<uses-permission android:name="android.permission.INTERNET"/>
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/ilyluo/article/details/51008494
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-28 04:07:25
  • 阅读 ( 1284 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢