下面简单铺一下代码:

(一)头像裁切、上传服务器(代码)

这里上边的按钮是头像的点击事件,弹出底部的头像选择框,下边的按钮跳到下个页面,进行原图上传。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.avatarImg:// 更换头像点击事件
        menuWindow = new SelectPicPopupWindow(mContext, itemsOnClick); 
        menuWindow.showAtLocation(findViewById(R.id.mainLayout),
                Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);
        break;
    case R.id.loginBtn://登录按钮跳转事件
        startActivity(new Intent(mContext, UploadActivity.class));
        break;
 
    default:
        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
//为弹出窗口实现监听类 
private OnClickListener itemsOnClick = new OnClickListener() {
    @Override
    public void onClick(View v) {
        menuWindow.dismiss();
        switch (v.getId()) {
        // 拍照
        case R.id.takePhotoBtn:
            Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            //下面这句指定调用相机拍照后的照片存储的路径
            takeIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                    Uri.fromFile(new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME)));
            startActivityForResult(takeIntent, REQUESTCODE_TAKE);
            break;
        // 相册选择图片
        case R.id.pickPhotoBtn:
            Intent pickIntent = new Intent(Intent.ACTION_PICK, null);
            // 如果朋友们要限制上传到服务器的图片类型时可以直接写如:image/jpeg 、 image/png等的类型
            pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image/*);
            startActivityForResult(pickIntent, REQUESTCODE_PICK);
            break;
        default:
            break;
        }
    }
};

为图像选取返回的接收处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
     
    switch (requestCode) {
    case REQUESTCODE_PICK:// 直接从相册获取
        try {
            startPhotoZoom(data.getData());
        } catch (NullPointerException e) {
            e.printStackTrace();// 用户点击取消操作
        }
        break;
    case REQUESTCODE_TAKE:// 调用相机拍照
        File temp = new File(Environment.getExternalStorageDirectory() + / + IMAGE_FILE_NAME);
        startPhotoZoom(Uri.fromFile(temp));
        break;
    case REQUESTCODE_CUTTING:// 取得裁剪后的图片
        if (data != null) {
            setPicToView(data);
        }
        break;
    }
    super.onActivityResult(requestCode, resultCode, data);
}

把图片显示出来,然后上传

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
 * 裁剪图片方法实现
 * @param uri
 */
public void startPhotoZoom(Uri uri) {
    Intent intent = new Intent(com.android.camera.action.CROP);
    intent.setDataAndType(uri, image/*);
    // crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
    intent.putExtra(crop, true);
    // aspectX aspectY 是宽高的比例
    intent.putExtra(aspectX, 1);
    intent.putExtra(aspectY, 1);
    // outputX outputY 是裁剪图片宽高
    intent.putExtra(outputX, 300);
    intent.putExtra(outputY, 300);
    intent.putExtra(return-data, true);
    startActivityForResult(intent, REQUESTCODE_CUTTING);
}
     
/**
 * 保存裁剪之后的图片数据
 * @param picdata
 */
private void setPicToView(Intent picdata) {
    Bundle extras = picdata.getExtras();
    if (extras != null) {
        // 取得SDCard图片路径做显示
        Bitmap photo = extras.getParcelable(data);
        Drawable drawable = new BitmapDrawable(null, photo);
        urlpath = FileUtil.saveFile(mContext, temphead.jpg, photo);
        avatarImg.setImageDrawable(drawable);
 
        // 新线程后台上传服务端
        pd = ProgressDialog.show(mContext, null, 正在上传图片,请稍候...);
        new Thread(uploadImageRunnable).start();
    }
}
 
/**
 * 使用HttpUrlConnection模拟post表单进行文件
 * 上传平时很少使用,比较麻烦
 * 原理是: 分析文件上传的数据格式,然后根据格式构造相应的发送给服务器的字符串。
 */
Runnable uploadImageRunnable = new Runnable() {
    @Override
    public void run() {
         
        if(TextUtils.isEmpty(imgUrl)){
            Toast.makeText(mContext, 还没有设置上传服务器的路径!, Toast.LENGTH_SHORT).show();
            return;
        }
         
        Map<string, string=""> textParams = new HashMap<string, string="">();
        Map<string, file=""> fileparams = new HashMap<string, file="">();
         
        try {
            // 创建一个URL对象
            URL url = new URL(imgUrl);
            textParams = new HashMap<string, string="">();
            fileparams = new HashMap<string, file="">();
            // 要上传的图片文件
            File file = new File(urlpath);
            fileparams.put(image, file);
            // 利用HttpURLConnection对象从网络中获取网页数据
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 设置连接超时(记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作)
            conn.setConnectTimeout(5000);
            // 设置允许输出(发送POST请求必须设置允许输出)
            conn.setDoOutput(true);
            // 设置使用POST的方式发送
            conn.setRequestMethod(POST);
            // 设置不使用缓存(容易出现问题)
            conn.setUseCaches(false);
            conn.setRequestProperty(Charset, UTF-8);//设置编码  
            // 在开始用HttpURLConnection对象的setRequestProperty()设置,就是生成HTML文件头
            conn.setRequestProperty(ser-Agent, Fiddler);
            // 设置contentType
            conn.setRequestProperty(Content-Type, multipart/form-data; boundary= + NetUtil.BOUNDARY);
            OutputStream os = conn.getOutputStream();
            DataOutputStream ds = new DataOutputStream(os);
            NetUtil.writeStringParams(textParams, ds);
            NetUtil.writeFileParams(fileparams, ds);
            NetUtil.paramsEnd(ds);
            // 对文件流操作完,要记得及时关闭
            os.close();
            // 服务器返回的响应吗
            int code = conn.getResponseCode(); // 从Internet获取网页,发送请求,将网页以流的形式读回来
            // 对响应码进行判断
            if (code == 200) {// 返回的响应码200,是成功
                // 得到网络返回的输入流
                InputStream is = conn.getInputStream();
                resultStr = NetUtil.readString(is);
            } else {
                Toast.makeText(mContext, 请求URL失败!, Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        handler.sendEmptyMessage(0);// 执行耗时的方法之后发送消给handler
    }
};
 
Handler handler = new Handler(new Handler.Callback() {
     
    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
        case 0:
            pd.dismiss();
             
            try {
                // 返回数据示例,根据需求和后台数据灵活处理
                // {status:1,statusMessage:上传成功,imageUrl:http://120.24.219.49/726287_temphead.jpg}
                JSONObject jsonObject = new JSONObject(resultStr);
                 
                // 服务端以字符串“1”作为操作成功标记
                if (jsonObject.optString(status).equals(1)) {
                    BitmapFactory.Options option = new BitmapFactory.Options();
                    // 压缩图片:表示缩略图大小为原始图片大小的几分之一,1为原图,3为三分之一
                    option.inSampleSize = 1;
                     
                    // 服务端返回的JsonObject对象中提取到图片的网络URL路径
                    String imageUrl = jsonObject.optString(imageUrl);
                    Toast.makeText(mContext, imageUrl, Toast.LENGTH_SHORT).show();
                }else{
                    Toast.makeText(mContext, jsonObject.optString(statusMessage), Toast.LENGTH_SHORT).show();
                }
                 
            } catch (JSONException e) {
                e.printStackTrace();
            }
             
            break;
             
        default:
            break;
        }
        return false;
    }
});</string,></string,></string,></string,></string,></string,>

(二)普通图片上传服务器(代码)

直接从这里开始,和头像那里基本没什么区别,我把拍照什么的单独抽出了方法,思路更清晰

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//为弹出窗口实现监听类 
private OnClickListener itemsOnClick = new OnClickListener() {
    @Override
    public void onClick(View v) {
        // 隐藏弹出窗口
        menuWindow.dismiss();
         
        switch (v.getId()) {
        case R.id.takePhotoBtn:// 拍照
            takePhoto();
            break;
        case R.id.pickPhotoBtn:// 相册选择图片
            pickPhoto();
            break;
        case R.id.cancelBtn:// 取消
            break;
        default:
            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
/**
 * 拍照获取图片
 */
private void takePhoto() {
    // 执行拍照前,应该先判断SD卡是否存在
    String SDState = Environment.getExternalStorageState();
    if (SDState.equals(Environment.MEDIA_MOUNTED)) {
 
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        /***
         * 需要说明一下,以下操作使用照相机拍照,拍照后的图片会存放在相册中的
         * 这里使用的这种方式有一个好处就是获取的图片是拍照后的原图
         * 如果不使用ContentValues存放照片路径的话,拍照后获取的图片为缩略图不清晰
         */
        ContentValues values = new ContentValues();
        photoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoUri);
        startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO);
    } else {
        Toast.makeText(this, 内存卡不存在, Toast.LENGTH_LONG).show();
    }
}
 
/***
 * 从相册中取图片
 */
private void pickPhoto() {
    Intent intent = new Intent();
    // 如果要限制上传到服务器的图片类型时可以直接写如:image/jpeg 、 image/png等的类型
    intent.setType(image/*);
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);
}

处理一下图片选取的页面回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 点击取消按钮
        if(resultCode == RESULT_CANCELED){
            return;
        }
         
        // 可以使用同一个方法,这里分开写为了防止以后扩展不同的需求
        switch (requestCode) {
        case SELECT_PIC_BY_PICK_PHOTO:// 如果是直接从相册获取
            doPhoto(requestCode, data);
            break;
        case SELECT_PIC_BY_TACK_PHOTO:// 如果是调用相机拍照时
            doPhoto(requestCode, data);
            break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

接下来就是显示图片和上传服务器了,上传和头像是同一个流程,只是不进行裁切

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
 * 选择图片后,获取图片的路径
 *
 * @param requestCode
 * @param data
 */
private void doPhoto(int requestCode, Intent data) {
     
    // 从相册取图片,有些手机有异常情况,请注意
    if (requestCode == SELECT_PIC_BY_PICK_PHOTO) {
        if (data == null) {
            Toast.makeText(this, 选择图片文件出错, Toast.LENGTH_LONG).show();
            return;
        }
        photoUri = data.getData();
        if (photoUri == null) {
            Toast.makeText(this, 选择图片文件出错, Toast.LENGTH_LONG).show();
            return;
        }
    }
     
    String[] pojo = { MediaColumns.DATA };
    // The method managedQuery() from the type Activity is deprecated
    //Cursor cursor = managedQuery(photoUri, pojo, null, null, null);
    Cursor cursor = mContext.getContentResolver().query(photoUri, pojo, null, null, null);
    if (cursor != null) {
        int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);
        cursor.moveToFirst();
        picPath = cursor.getString(columnIndex);
         
        // 4.0以上的版本会自动关闭 (4.0--14;; 4.0.3--15)
        if (Integer.parseInt(Build.VERSION.SDK) < 14) {
            cursor.close();
        }
    }
     
    // 如果图片符合要求将其上传到服务器
    if (picPath != null && (    picPath.endsWith(.png) ||
                                picPath.endsWith(.PNG) ||
                                picPath.endsWith(.jpg) ||
                                picPath.endsWith(.JPG))) {
 
         
        BitmapFactory.Options option = new BitmapFactory.Options();
        // 压缩图片:表示缩略图大小为原始图片大小的几分之一,1为原图
        option.inSampleSize = 1;
        // 根据图片的SDCard路径读出Bitmap
        Bitmap bm = BitmapFactory.decodeFile(picPath, option);
        // 显示在图片控件上
        picImg.setImageBitmap(bm);
         
        pd = ProgressDialog.show(mContext, null, 正在上传图片,请稍候...);
        new Thread(uploadImageRunnable).start();
    } else {
        Toast.makeText(this, 选择图片文件不正确, Toast.LENGTH_LONG).show();
    }
 
}
 
/**
 * 使用HttpUrlConnection模拟post表单进行文件
 * 上传平时很少使用,比较麻烦
 * 原理是: 分析文件上传的数据格式,然后根据格式构造相应的发送给服务器的字符串。
 */
Runnable uploadImageRunnable = new Runnable() {
    @Override
    public void run() {
         
        if(TextUtils.isEmpty(imgUrl)){
            Toast.makeText(mContext, 还没有设置上传服务器的路径!, Toast.LENGTH_SHORT).show();
            return;
        }
         
        Map<string, string=""> textParams = new HashMap<string, string="">();
        Map<string, file=""> fileparams = new HashMap<string, file="">();
         
        try {
            // 创建一个URL对象
            URL url = new URL(imgUrl);
            textParams = new HashMap<string, string="">();
            fileparams = new HashMap<string, file="">();
            // 要上传的图片文件
            File file = new File(picPath);
            fileparams.put(image, file);
            // 利用HttpURLConnection对象从网络中获取网页数据
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 设置连接超时(记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作)
            conn.setConnectTimeout(5000);
            // 设置允许输出(发送POST请求必须设置允许输出)
            conn.setDoOutput(true);
            // 设置使用POST的方式发送
            conn.setRequestMethod(POST);
            // 设置不使用缓存(容易出现问题)
            conn.setUseCaches(false);
            // 在开始用HttpURLConnection对象的setRequestProperty()设置,就是生成HTML文件头
            conn.setRequestProperty(ser-Agent, Fiddler);
            // 设置contentType
            conn.setRequestProperty(Content-Type, multipart/form-data; boundary= + NetUtil.BOUNDARY);
            OutputStream os = conn.getOutputStream();
            DataOutputStream ds = new DataOutputStream(os);
            NetUtil.writeStringParams(textParams, ds);
            NetUtil.writeFileParams(fileparams, ds);
            NetUtil.paramsEnd(ds);
            // 对文件流操作完,要记得及时关闭
            os.close();
            // 服务器返回的响应吗
            int code = conn.getResponseCode(); // 从Internet获取网页,发送请求,将网页以流的形式读回来
            // 对响应码进行判断
            if (code == 200) {// 返回的响应码200,是成功
                // 得到网络返回的输入流
                InputStream is = conn.getInputStream();
                resultStr = NetUtil.readString(is);
            } else {
                Toast.makeText(mContext, 请求URL失败!, Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        handler.sendEmptyMessage(0);// 执行耗时的方法之后发送消给handler
    }
};
 
Handler handler = new Handler(new Handler.Callback() {
 
    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
        case 0:
            pd.dismiss();
             
            try {
                JSONObject jsonObject = new JSONObject(resultStr);
                // 服务端以字符串“1”作为操作成功标记
                if (jsonObject.optString(status).equals(1)) {
 
                    // 用于拼接发布说说时用到的图片路径
                    // 服务端返回的JsonObject对象中提取到图片的网络URL路径
                    String imageUrl = jsonObject.optString(imageUrl);
                    // 获取缓存中的图片路径
                    Toast.makeText(mContext, imageUrl, Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(mContext, jsonObject.optString(statusMessage), Toast.LENGTH_SHORT).show();
                }
                 
            } catch (JSONException e) {
                e.printStackTrace();
            }
            break;
        default:
            break;
        }
        return false;
    }
});</string,></string,></string,></string,></string,></string,>
 

结伴旅游,一个免费的交友网站:www.jieberu.com

推推族,免费得门票,游景区:www.tuituizu.com

Android图片上传(头像裁切+原图原样)的更多相关文章

  1. Android 图片上传

    上传方式:两种   1:Base64() (1):获取图片路径,将图片转为String 类型 (2):通过post提交的方式.以键值对的方式上传到服务器,和一般的提交关键字没有任何区别. (3):这种 ...

  2. vue 剪切图片上传头像,使用 cropperjs 实现

    我使用的是vue,移动端的项目. 官网地址:cropperjs GitHub地址:https://github.com/fengyuanchen/cropperjs/blob/master/READM ...

  3. Android图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  4. Android图片上传问题小结

    1.图片的显示 出现OOM,原因一般为图片太大, 直接进行尺寸压缩即可. 2.图片的上传(服务器有大小限制) 出现OOM,原因一般为图片太大, 做一次尺寸压缩, 再做一次质量压缩,压缩质量(0-100 ...

  5. android 图片上传到服务端 文件损坏问题

    在网上找的例子,怎么试都不行. 上传上去之后提示文件损坏,不过最后问题还是找到了. 是因为不能在写入流的byte中写入其他内容 这是网上的例子 如果是要在服务端取文件名,可以在这里写入 在服务端获取文 ...

  6. android图片上传

    package com.example.center; import java.io.ByteArrayOutputStream;import java.io.InputStream; import ...

  7. html图片上传阅览并且点击放大

                  关闭   qq_31540195的博客       目录视图 摘要视图 订阅 异步赠书:9月重磅新书升级,本本经典           程序员9月书讯      每周荐书: ...

  8. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  9. 「小程序JAVA实战」小程序头像图片上传(下)(45)

    转自:https://idig8.com/2018/09/09/xiaochengxujavashizhanxiaochengxutouxiangtupianshangchuan44/ 接下来,我们应 ...

随机推荐

  1. web框架 Spring+SpringMvc+Jpa 纯注解搭建

    0.jar包依赖 maven  pom.xml <properties> <spring_version>4.3.25.RELEASE</spring_version&g ...

  2. Python中字典合并的四种方法

    字典是Python语言中唯一的映射类型.映射类型对象里哈希值(键,key)和指向的对象(值,value)是一对多的的关系,通常被认为是可变的哈希表.字典对象是可变的,它是一个容器类型,能存储任意个数的 ...

  3. 吴恩达深度学习:2.12向量化logistic回归

    1.不使用任何for循环用梯度下降实现整个训练集的一步迭代. (0)我们已经讨论过向量化如何显著加速代码,在这次视频中我们会设计向量化是如何实现logistic回归,这样酒桶同时处理m个训练集,来实现 ...

  4. 国内高速下载Docker

    一般情况下,我们可以从Docker官网下载docker安装文件,但是官方网站由于众所周知的原因,不是访问慢,就是下载慢.下载docker安装包动不动就要个把小时,真是极大的影响工作效率. 在这里推荐一 ...

  5. 2019-11-29-Roslyn-如何在-Target-引用-xaml-防止文件没有编译

    title author date CreateTime categories Roslyn 如何在 Target 引用 xaml 防止文件没有编译 lindexi 2019-11-29 08:58: ...

  6. Win7 Linux双系统,恢复Linux启动项

    在一台电脑上安装Win7 Centos双系统,先安装Win,再安装Centos7.装完后,丢失Linux启动项. 恢复步骤,下载EasyBCD,添加新条目,操作系统选择Linux/BSD,类型选择GR ...

  7. 神奇的AI:将静态图片转为3D动图

    近日我们从外媒获得消息,位于莫斯科的三星AI中心和Skolkovo科学技术研究所的研究人员发表了一篇新论文,详细介绍了从单个静止人像照片生成3D动画人像的创建.与此前能够生成照片般逼真肖像的人工智能A ...

  8. usermod 修改用户信息

    7.2 usermod 修改用户信息 1.命令功能 usermod 修改已存在的用户账号信息. 2.语法格式 usermod option login 参数选项说明 选项 选项说明 -c 修改用户pa ...

  9. zencart后台修改首页meta_title、meta_keywords、meta_description

    includes\languages\english\模板\meta_tags.php 首先,将meta_tags.php中常量HOME_PAGE_META_DESCRIPTION.HOME_PAGE ...

  10. Codeforces 981 共同点路径覆盖树构造 BFS/DP书架&最大值

    A /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define pb push_bac ...