美文网首页安卓开发学习安卓开发安卓资源收集
Android学习-使用Async-Http实现图片压缩并上传功

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

作者: 08dc70a40fb1 | 来源:发表于2016-06-14 00:26 被阅读1523次

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

    前言

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

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

    效果图

    安卓端 服务器端

    解决

    安卓端

    一、点击加载本地相册选择图片,然后加载到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);
            }
        });
    

    //在选择图片后返回本界面调用此方法
    @Override
    protected 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);
        }
    }
    

    Demo地址

    http://download.csdn.net/detail/ljcitworld/9548619

    相关文章

      网友评论

        本文标题:Android学习-使用Async-Http实现图片压缩并上传功

        本文链接:https://www.haomeiwen.com/subject/tytudttx.html