Android_头像裁剪上传(客户端+服务器)

来源:互联网 发布:如何开一个淘宝网店 编辑:程序博客网 时间:2024/05/16 19:20

DO
文章转载自:http://www.2cto.com/kf/201501/371520.html

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

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

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

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

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

**

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

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

//为弹出窗口实现监听类  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;        }    }};
/** * 拍照获取图片 */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);}

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

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

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

/** * 选择图片后,获取图片的路径 *  * @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;    }});
1 0
原创粉丝点击