还是那句话,最近项目比较忙拖了很久这篇文章终于完成了!

先看一下效果图:

(一)头像裁切、上传服务器(效果图)

一般都是有圆形显示头像的,这里我自定义了一个ImageView,页面很干净但是看着很上档次吧!

点击头像从底部弹出一个对话框,提示用户头像来自相机或者相册,这都是常规流程。

上传完成后默认的“程序员头像”换成了萌妹子

(二)普通图片上传服务器(效果图)

模仿QQ空间发动态的布局随意捏造一个界面出来

点击添加图片从底部弹出一个对话框,提示用户图片来自相机或者相册,这也都是常规流程。

上传过程中,有可能图片很大,显示一个进度圈(其实头像上传也有,只是文件小,还没显示就上传完成了

上传完成后把刚才的照片亮出来显示到按钮的地方,当然大家根据需要还可以自己扩展(比如长按抖动出现删除、继续添加N张等等)

下面简单铺一下代码:

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

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

 @Overridepublic 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;}}

弹出窗绑定一个按钮事件

 //为弹出窗口实现监听类  private OnClickListener itemsOnClick = new OnClickListener() {@Overridepublic 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;}}}; 

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

 @Overridepublic 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);}

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

 /*** 裁剪图片方法实现* @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() {@Overridepublic 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");// 设置contentTypeconn.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() {@Overridepublic 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;}});

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

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

 //为弹出窗口实现监听类  private OnClickListener itemsOnClick = new OnClickListener() {@Overridepublic 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;}}}; 
 /*** 拍照获取图片*/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);}

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

@Overrideprotected 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);}

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

 /*** 选择图片后,获取图片的路径* * @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路径读出BitmapBitmap 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() {@Overridepublic 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");// 设置contentTypeconn.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() {@Overridepublic 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;}});

最后放上 完整的代码!大家上传路径自己搭建啊!

采集
采集

Android图片上传(头像裁切+原图原样)相关推荐

  1. 图片上传压缩android,android 图片上传压缩常见问题分析

    图片的上传与压缩是android经常需要用到的步骤,那么,如何解决上传图片oom问题呢?android 图片上传压缩常见问题分析,希望可以帮助大家更加的了解android 图片方面的困惑. 下面,是我 ...

  2. 【小程序开发原创】小程序裁剪图片上传头像,二维码源码

    微信小程序 图片裁剪工具,简单易用 项目需求 在做微信小程序的时候有个图片上传之前裁剪的需求,找过一些github中的项目,都不太理想,主要是没有办法自定义宽高,于是自己研究了一下,做了一个简单的图片 ...

  3. Android kotlin上传头像实现

    Android 上传头像基本上是每个app都有的功能,虽然看起来简单,但是作为新手的我实现起来却没有那么简单,实现如下 从相册获取照片,代码如下 //从相册获取照片private fun getFro ...

  4. android mysql上传头像,Android自定义控件仿QQ编辑和选取圆形头像

    android大家都有很多需要用户上传头像的需求,有的是选方形,有的是圆角矩形,有的是圆形. 首先我们要做一个处理图片的自定义控件,把传入的图片,经过用户选择区域,处理成一定的形状. 有的app是通过 ...

  5. 前端图片上传并且裁切

    本文讲的图片上传,主要是针对上传头像的.大家都知道,上传头像一般都会分成以下 4 个步骤: 选择图片 -> 预览图片 -> 裁剪图片  -> 上传图片 接下来,就详细的介绍每个步骤具 ...

  6. Android图片上传的两种方式

    图片上传,以及带参数的图片上传是Android开发中,很常见的需求.但也是接口联调难度相对比较大的技术实现,本文介绍两种可靠的图片上传方式.一是通过 MultipartBody 来实现:二是通过图片转 ...

  7. android图片上传后台后旋转的关键原因:ExifInterface

    先说照片 出问题的都是jpg照片,一个完整的照片分为两部分, 一部分是:照片信息,照片信息存有里有照片里的很多东西,包括照片方向,拍摄位置,分辨率,长宽高等等,在这里对我们影响最大的是:旋转的方向以及 ...

  8. Android图片上传服务器(File格式)

    1.首先我们需要声明几个变量 TreeMap<String, String> paramsMap;. RequestBody requestBody = null; Request req ...

  9. 玩转 Android图片上传

    在Android开发中经常会遇到需要上传图片的场景,虽然现在有很多很好的第三方框架可供使用,而且傻瓜集成,配置简单.但是有些时候总感觉第三方框架过于臃肿,用着总感觉没有自己写的来得踏实.所以让我们也任 ...

最新文章

  1. python爬虫实例100-Python 练习实例1
  2. jQuery EasyUI API 中文文档 - 链接按钮(LinkButton)
  3. centos 6.3安装libmcrypt-2.5.8不成功解决方案
  4. SAR图像变化检测的评价方法
  5. LeetCode:Remove Duplicates from Sorted List I II
  6. php7的核心开发者,php7 五大新特性
  7. 踩过的坑 vertical-alignline-height
  8. 云豹直播源码v8.2
  9. 用python 调用whatsapp自动发消息
  10. pmp效益管理计划和做题技巧
  11. WPS使用宏操作——减少重复性操作,提高效率
  12. 惠普触控板使用指南_惠普笔记本关闭触摸板【操作思路】
  13. 计算机图形学笔记 || 基本图形的扫描转换
  14. 前端js——金山打字通小游戏(屏幕随机下落字母,获取键盘按键)
  15. 如何阻止事件冒泡与默认事件?
  16. Ubuntu 18.04 创建 mdadm RAID0
  17. 注会 第三章 存货
  18. IOT_WIFI/LORA/THREAD/ZIGBEE/NFC/RFID/EnOcean
  19. 经营棋牌室的难点和痛点
  20. 软件推荐:多屏协作scrcpy

热门文章

  1. Designing a Poster 海报设计教程 Lynda课程中文字幕
  2. python用Levenshtein计算文本相似度(附带所有个人对函数的理解)
  3. 【附源码】Java计算机毕业设计家居装修网站(程序+LW+部署)
  4. 关于Python3爬虫之写为朋友设计签名的小程序
  5. 微信小程序接入腾讯云IM即时通讯(获取聊天历史记录开发步骤)
  6. Git 学习之路-1
  7. Java条码解码zxing
  8. speedoffice如何设置首字下沉效果
  9. SqlTransaction事务的用法
  10. 蒙特卡洛树搜索(MCTS)代码详解【python】