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

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

文章转载自:
作者:RyaneLee
链接:http://www.jianshu.com/p/940fc7ba39e1

让我头疼一个星期的图片批量上传服务器的问题最后受这篇文章的作者启发而解决,自己之前一直执着于通过uri地址找到图片然后上传图片,却没想过直接上传图片本身。感谢作者的博客和启发。

前言

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

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

效果图

安卓端

服务器端

解决

安卓端

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

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

 1 //在选择图片后返回本界面调用此方法
 2 @Override
 3 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 4     if (requestCode == 0x1 && resultCode == RESULT_OK) {
 5         if (data != null) {
 6
 7             ContentResolver resolver = getContentResolver();
 8             try {
 9                 // 获取圖片URI
10                 Uri uri = data.getData();
11                 // 将URI转换为路径:
12                 String[] proj = { MediaStore.Images.Media.DATA };
13                 Cursor cursor = managedQuery(uri, proj, null, null, null);
14                 //  这个是获得用户选择的图片的索引值
15                 int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
16                 cursor.moveToFirst();
17                 // 最后根据索引值获取图片路径
18                 photoPath = cursor.getString(column_index);
19
20                 // 压缩成800*480
21                 bitmap = BitmapUtils.decodeSampledBitmapFromFd(photoPath, 480, 800);
22                 // 设置imageview显示图片
23                 photo.setImageBitmap(bitmap);
24                 // 设置textview显示路径
25                 path.setText(photoPath);
26             } catch (Exception e) {
27                 e.printStackTrace();
28             }
29
30         }
31     }
32 }
 

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

 1 public class BitmapUtils {
 2
 3     private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
 4         final int height = options.outHeight;
 5         final int width = options.outWidth;
 6         int inSampleSize = 1;
 7         if (height > reqHeight || width > reqWidth) {
 8             //首先获取原图高度和宽度的一半
 9             final int halfHeight = height / 2;
10             final int halfWidth = width / 2;
11             //循环,如果halfHeight和halfWidth同时大于最小宽度和最小高度时,inSampleSize乘2,
12             //最后得到的宽或者高都是最接近最小宽度或者最小高度的
13             while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
14                 inSampleSize *= 2;
15             }
16         }
17         return inSampleSize;
18     }
19
20     /**
21      * 根据Resources压缩图片
22      *
23      * @param res
24      * @param resId
25      * @param reqWidth
26      * @param reqHeight
27      * @return
28      */
29     public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
30         final BitmapFactory.Options options = new BitmapFactory.Options();
31         options.inJustDecodeBounds = true;
32         BitmapFactory.decodeResource(res, resId, options);
33         options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
34         options.inJustDecodeBounds = false;
35         Bitmap src = BitmapFactory.decodeResource(res, resId, options);
36         return src;
37     }
38
39     /**
40      * 根据地址压缩图片
41      *
42      * @param pathName
43      * @param reqWidth 最小宽度
44      * @param reqHeight 最小高度
45      * @return
46      */
47     public static Bitmap decodeSampledBitmapFromFd(String pathName, int reqWidth, int reqHeight) {
48         final BitmapFactory.Options options = new BitmapFactory.Options();
49         // 若要对图片进行压缩,必须先设置Option的inJustDecodeBounds为true才能进行Option的修改
50         options.inJustDecodeBounds = true;
51         // 第一次decodeFile是获取到options.outHeight和options.outWidth
52         BitmapFactory.decodeFile(pathName, options);
53         // options.inSampleSize是图片的压缩比,例如原来大小是100*100,options.inSampleSize为1,则不变,
54         // options.inSampleSize为2,则压缩成50*50
55         options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
56         // 重新设置options.inJustDecodeBounds为false,不能修改option
57         options.inJustDecodeBounds = false;
58         // 根据options重新加载图片
59         Bitmap src = BitmapFactory.decodeFile(pathName, options);
60         return src;
61     }
62 }
 

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

 1 public class Utils {
 2     // 将bitmap转成string类型通过Base64
 3     public static String BitmapToString(Bitmap bitmap) {
 4
 5         ByteArrayOutputStream bao = new ByteArrayOutputStream();
 6         // 将bitmap压缩成30%
 7         bitmap.compress(Bitmap.CompressFormat.JPEG, 30, bao);
 8         // 将bitmap转化为一个byte数组
 9         byte[] bs = bao.toByteArray();
10         // 将byte数组用BASE64加密
11         String photoStr = Base64.encodeToString(bs, Base64.DEFAULT);
12         // 返回String
13         return photoStr;
14     }
15 }
 

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

 1  public void upload(String url) {
 2         // 将bitmap转为string,并使用BASE64加密
 3         String photo = Utils.BitmapToString(bitmap);
 4         // 获取到图片的名字
 5         String name = photoPath.substring(photoPath.lastIndexOf("/")).substring(1);
 6         // new一个请求参数
 7         RequestParams params = new RequestParams();
 8         // 将图片和名字添加到参数中
 9         params.put("photo", photo);
10         params.put("name", name);
11         AsyncHttpClient client = new AsyncHttpClient();
12         // 调用AsyncHttpClient的post方法
13         client.post(url, params, new AsyncHttpResponseHandler() {
14
15             @Override
16             public void onFailure(int arg0, Header[] arg1, byte[] arg2, Throwable arg3) {
17                 Toast.makeText(getApplicationContext(), "上传失败!", Toast.LENGTH_SHORT).show();
18             }
19
20             @Override
21             public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
22                 Toast.makeText(getApplicationContext(), "上传成功!", Toast.LENGTH_SHORT).show();
23             }
24         });
25     }

服务器端

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

 1 public class UpLoadPhotoServlet extends HttpServlet {
 2     /**
 3      *
 4      */
 5     private static final long serialVersionUID = 1L;
 6
 7     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 8         request.setCharacterEncoding("utf-8");
 9         response.setCharacterEncoding("utf-8");
10         response.setContentType("text/html");
11         // 获取文件名
12         String name = request.getParameter("name");
13         // 获取图片
14         String photo = request.getParameter("photo");
15         // 将传进来的图片的string格式进行处理
16         byte[] bs = new BASE64Decoder().decodeBuffer(photo);
17         // 写到E盘Img文件夹下的a.jpg文件。注:Img文件夹一定要存在
18         FileOutputStream fos = new FileOutputStream("E:/Img/" + name);
19         fos.write(bs);
20         fos.flush();
21         fos.close();
22
23         PrintWriter writer = response.getWriter();
24         writer.print("上传成功");
25     }
26
27     @Override
28     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
29         doGet(req, resp);
30     }
31 }
 

Demo地址

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

时间: 09-15

(转)Android学习-使用Async-Http实现图片压缩并上传功能的相关文章

前端获取图片压缩后上传给后台

 此前有同事跟我聊过关于移动端用canvas压缩图片后再上传的功能,最近有了点空闲时间,所以就实践了一下.demo效果链接在文章底部贴出. 在做移动端图片上传的时候,用户传的都是手机本地图片,而本地图片一般都相对比较大,拿iphone6来说,平时拍很多图片都是一两M的,如果直接这样上传,那图片就太大了,如果用户用的是移动流量,完全把图片上传显然不是一个好办法. 目前来说,HTML5的各种新API都在移动端的webkit上得到了较好的 实现.根据查看caniuse,本demo里使用到的FileRe

项目分享五:H5图片压缩与上传

一.简介 图片的压缩与上传,是APP里一个很常用的功能.我们来年看 ChiTuStore 是怎样做的.相关文件 App/Module/User/UserInfo.html,App/Module/User/UserInfo.ts 二.HTML布局 HTML 文件中,有如下二句,第一句就是上图所看到的图片,其中的 class 表示该图片以圆形来显示,并且靠右.第二句是一个 Input 控件,其类型为 file ,是用来上传文件的.值得注意的是 style,这的作用是让该控件与图片重叠,并且透明(op

PHP仿微信多图片预览上传功能

PHP仿微信多图片预览下载演示地址:http://www.erdangjiade.com/js...生产图片区域,上传按钮#btn可替换自己想要的图片 [html] view plain copy在CODE上查看代码片派生到我的代码片 <ul id="ul_pics" class="ul_pics clearfix"> <li><img src="logo.png" id="btn" class=

js图片压缩并上传?

js: var eleFile = document.querySelector('#file'); // 压缩图片需要的一些元素和对象 var reader = new FileReader(); var imga=document.getElementById('imga'); var img = new Image(); // base64地址图片加载完毕后 img.onload = function() { var originWidth = this.width, //image re

JSP+SpringMVC框架使用WebUploader插件实现注册时候头像图片的异步上传功能

一.去官网下载webuploader文件上传插件 https://fex.baidu.com/webuploader/ 下载好后把它放到Javaweb项目的文件夹中(我放到了webcontent下面的static里面) 二.复制前端的样式 把这段代码放到你想要放到的位置(刷新页面和示例中不一样?不用担心因为你还没有初始化{就是还没有导入swf文件},指定路径后刷新应该就好了) 三.复制实现文件异步上传的js代码(这里我们只复制图片上传的部分) js源码的中文是乱码,应该是缺少谷歌改编码格式的插件

ueditor单独图片和附件上传功能

首要要载入ueditor的2个js <script src="../ueditor/ueditor.config.js" type="text/javascript"></script> <script src="../ueditor/ueditor.all.js" type="text/javascript"></script> <table> <tr>

HTML5实现图片压缩上传功能

上篇文章中提到移动端上传图片,我们知道现在流量还是挺贵的,手机的像素是越来越高,拍个照动不动就是好几M,伤不起.虽然客户端可以轻轻松松实现图片压缩再上传,但是我们的应用还可能在浏览器里面打开,怎么办呢,图片压缩.受以前PC上的开发思维影响,尼玛js哪有权限去操作文件,哪有资格压缩图片啊,搞不了,你们客户端去整吧.只能说自己还是有些井底之蛙了.在HTML5的影响下,前端能干的事情越来越多了,开发的功能逼格也越来越高了,H5万岁!前端的魅力也在这,过去不可能的并不意味现在.以后不可能,努力吧,骚年!

如何有效实现前端压缩图片并上传功能

随着现在手机的像素越来越高,很多照片动辄几兆甚至十几兆,上传后在服务器端压缩已经越来越不能满足当今的需求.这对于许多技术人员来说,处理起来这样的问题往往不知道该怎么下手,那么下面就跟大家讲解一下如何在前端进行图片压缩后上传到服务器. 以上传单张图片为例,多张图片同理,多嵌套一层循环即可.代码实现如下: html: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta

Android学习笔记进阶之在图片上涂鸦(能清屏)

Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java [java] view plaincopy package xiaosi.handWriting; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import andro