手记

Android学习-使用Async-Http实现图片压缩并上传功能

Android学习-使用Async-Http实现图片压缩并上传功能

前言

(转载请注明出处,谢谢!)

最近在做一个小项目,项目中要实现上传图片到服务器,而这个例子是实现图片的尺寸压缩,将获取到的压缩图片转为流,然后使用Async-Http开源框架实现图片流的上传,然后在服务器端将流写入本地。

效果图

<center></center>
<center>安卓端</center>

<center></center>
<center>服务器端</center>

解决

安卓端

一、点击加载本地相册选择图片,然后加载到ImageView中去,并获取图片地址以供后面图片上传时使用。

        //点击图片打开选择图片界面
    photo.setOnClickListener(new OnClickListener() {        @Override
        public void onClick(View v) {            //使用Intent触发选择Action
            Intent intent = new Intent(Intent.ACTION_PICK, null);            //打开系统提供的图片选择界面
            intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");            //传参以在返回本界面时触发加载图片的功能
            startActivityForResult(intent, 0x1);
        }
    });

//在选择图片后返回本界面调用此方法@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    if (requestCode == 0x1 && resultCode == RESULT_OK) {        if (data != null) {

            ContentResolver resolver = getContentResolver();            try {                // 获取圖片URI
                Uri uri = data.getData();                // 将URI转换为路径:
                String[] proj = { MediaStore.Images.Media.DATA };
                Cursor cursor = managedQuery(uri, proj, null, null, null);                //  这个是获得用户选择的图片的索引值
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();                // 最后根据索引值获取图片路径
                photoPath = cursor.getString(column_index);                // 压缩成800*480
                bitmap = BitmapUtils.decodeSampledBitmapFromFd(photoPath, 480, 800);                // 设置imageview显示图片
                photo.setImageBitmap(bitmap);                // 设置textview显示路径
                path.setText(photoPath);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
}

二、图片压缩。在我们需要上传图片时,我们不可能直接把原图上传到服务器,因为一般图片的大小都超过3,4M,所以我们在上传之前需要对图片进行压缩,我是把图片压缩放到了一个工具类,主要是对图片进行尺寸压缩。

public class BitmapUtils {    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {        final int height = options.outHeight;        final int width = options.outWidth;        int inSampleSize = 1;        if (height > reqHeight || width > reqWidth) {            //首先获取原图高度和宽度的一半
            final int halfHeight = height / 2;            final int halfWidth = width / 2;            //循环,如果halfHeight和halfWidth同时大于最小宽度和最小高度时,inSampleSize乘2,
            //最后得到的宽或者高都是最接近最小宽度或者最小高度的
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }        return inSampleSize;
    }    /**
     * 根据Resources压缩图片
     * 
     * @param res
     * @param resId
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeResource(res, resId, options);        return src;
    }    /**
     * 根据地址压缩图片
     * 
     * @param pathName
     * @param reqWidth 最小宽度
     * @param reqHeight 最小高度
     * @return
     */
    public static Bitmap decodeSampledBitmapFromFd(String pathName, int reqWidth, int reqHeight) {        final BitmapFactory.Options options = new BitmapFactory.Options();        // 若要对图片进行压缩,必须先设置Option的inJustDecodeBounds为true才能进行Option的修改
        options.inJustDecodeBounds = true;        // 第一次decodeFile是获取到options.outHeight和options.outWidth
        BitmapFactory.decodeFile(pathName, options);        // options.inSampleSize是图片的压缩比,例如原来大小是100*100,options.inSampleSize为1,则不变,
        // options.inSampleSize为2,则压缩成50*50
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);        // 重新设置options.inJustDecodeBounds为false,不能修改option
        options.inJustDecodeBounds = false;        // 根据options重新加载图片
        Bitmap src = BitmapFactory.decodeFile(pathName, options);        return src;
    }
}

三、将Bitmap转为String,同时使用BASE64加密,使传输更加安全,这是我的工具类,里面再一次进行压缩是质量压缩,压缩比例是30%,具体自己调

public class Utils {    // 将bitmap转成string类型通过Base64
    public static String BitmapToString(Bitmap bitmap) {

        ByteArrayOutputStream bao = new ByteArrayOutputStream();        // 将bitmap压缩成30%
        bitmap.compress(Bitmap.CompressFormat.JPEG, 30, bao);        // 将bitmap转化为一个byte数组
        byte[] bs = bao.toByteArray();        // 将byte数组用BASE64加密
        String photoStr = Base64.encodeToString(bs, Base64.DEFAULT);        // 返回String
        return photoStr;
    }
}

四、通过Async-Http实现图片上传

    public void upload(String url) {        // 将bitmap转为string,并使用BASE64加密
        String photo = Utils.BitmapToString(bitmap);        // 获取到图片的名字
        String name = photoPath.substring(photoPath.lastIndexOf("/")).substring(1);        // new一个请求参数
        RequestParams params = new RequestParams();        // 将图片和名字添加到参数中
        params.put("photo", photo);
        params.put("name", name);
        AsyncHttpClient client = new AsyncHttpClient();        // 调用AsyncHttpClient的post方法
        client.post(url, params, new AsyncHttpResponseHandler() {            @Override
            public void onFailure(int arg0, Header[] arg1, byte[] arg2, Throwable arg3) {
                Toast.makeText(getApplicationContext(), "上传失败!", Toast.LENGTH_SHORT).show();
            }            @Override
            public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
                Toast.makeText(getApplicationContext(), "上传成功!", Toast.LENGTH_SHORT).show();
            }
        });
    }

服务器端

一、创建一个新的Servlet,在doget方法里面实现

public class UpLoadPhotoServlet extends HttpServlet {    /**
     * 
     */
    private static final long serialVersionUID = 1L;    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");        // 获取文件名
        String name = request.getParameter("name");        // 获取图片
        String photo = request.getParameter("photo");        // 将传进来的图片的string格式进行处理
        byte[] bs = new BASE64Decoder().decodeBuffer(photo);        // 写到E盘Img文件夹下的a.jpg文件。注:Img文件夹一定要存在
        FileOutputStream fos = new FileOutputStream("E:/Img/" + name);
        fos.write(bs);
        fos.flush();
        fos.close();

        PrintWriter writer = response.getWriter();
        writer.print("上传成功");
    }    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

原文链接:http://www.apkbus.com/blog-771645-62514.html

1人推荐
随时随地看视频
慕课网APP