Android-图片的上传及加载
2016-03-21 17:36
447 查看
在Android端和服务器端之间,图片的传输是以经过Base64编码过的字符串进行的;
所以整个过程如下(在过程中使用post网络传输):
Android端:图片编码----》服务器端:接收、解码,然后转换成图片,从服务器端到Android端一样的流程;
在图片编解码的过程中,byte[] 字节流充当着中间者的角色,即:图片---》inputstream流----》byte[]----》字符串。
下面我们就说一下具体是如何实现的:
Android端:
1、获取图片:在开发的过程中可以从计算机本地和andorid机中获取到图片
以绝对路径来获取本地图片:
此时图片已经转换成Bitmap对象,要把图片以Base64编码字符串的形式传输,还需要对Bitmap对象压缩
以上是android端的上传
然后就是服务器端的接收与转换
android端的接收、服务器端的接收与返回都是流与byte[]的转换,但在不同端编解码的方式有点不同:
注意事项:
在导入sun.misc.Base64Decoder等包时,系统会提示找不到,解决办法如下;
Windows -> Preferences -> Java -> Compiler -> Errors/Warnings ->
Deprecated and trstricted API -> Forbidden reference (access rules): -> change to warning
小贴士:
二进制数据要转成字符串来传输是需要经过编码(例如BASE64)处理才可以的;
1.在发送端用BASE64Encoder将二进制数据编码成字符串后再发送;
byte[] bt = <bt是读取到的图片的二制数据>;
String temp = new sun.misc.BASE64Encoder().encodeBuffer(bt);
2.在接收端用BASE64Decoder对接收到的字符串解码成二进制数据;再输出生成图片;
byte[] bt = new sun.misc.BASE64Decoder().decodeBuffer(temp);
所以整个过程如下(在过程中使用post网络传输):
Android端:图片编码----》服务器端:接收、解码,然后转换成图片,从服务器端到Android端一样的流程;
在图片编解码的过程中,byte[] 字节流充当着中间者的角色,即:图片---》inputstream流----》byte[]----》字符串。
下面我们就说一下具体是如何实现的:
Android端:
1、获取图片:在开发的过程中可以从计算机本地和andorid机中获取到图片
以绝对路径来获取本地图片:
InputStream in = new FileInputStream("F://image//a.jpg"); Bitmap bitmap = BitmapFactory.decodeStream(in);//流转换成图片从相册或拍照获取图片
private void UpdateHeadImage() { // TODO Auto-generated method stub MyHead_image.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(); /* 开启Pictures画面Type设定为image */ intent.setType("image/*"); /* 使用Intent.ACTION_GET_CONTENT这个Action */ intent.setAction(Intent.ACTION_GET_CONTENT); /* 取得相片后返回本画面 */ startActivityForResult(intent, 1); } }); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) {//RESULT_OK:Standard activity result: operation succeeded. Uri uri = data.getData(); Log.e("uri", uri.toString()); ContentResolver cr = this.getContentResolver(); try { in = cr.openInputStream(uri); bitmap = BitmapFactory.decodeStream(in); ImageView imageView = (ImageView) findViewById(R.id.main_image); /* 将Bitmap设定到ImageView */ imageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { Log.e("Exception", e.getMessage(),e); } } super.onActivityResult(requestCode, resultCode, data); } 下面是从相册和拍照获取图片 protected void getImageFromAlbum() { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*");//相片类型 startActivityForResult(intent, 0); } protected void getImageFromCamera() { String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE"); startActivityForResult(getImageByCamera, 1); } else { Toast.makeText(getActivity(), "请确认已经插入SD卡", Toast.LENGTH_LONG).show(); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub if(requestCode==REQUEST_CODE_IMAGE){ Uri uri = data.getData(); ContentResolver cr = getActivity().getContentResolver(); try { InputStream in = cr.openInputStream(uri); Bitmap Head_bitmap_image = BitmapFactory.decodeStream(in); LoadHead(Head_bitmap_image); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else if(requestCode==REQUEST_CODE_CAMERA){ Uri uri = data.getData(); //手机的不同,拍照获取到图片方式也可能不同 if(uri==null){ Log.i("camera_uri", "为空"); Bundle b = data.getExtras(); if(b!=null){ Bitmap Head_bitmap_camera = (Bitmap) b.get("data"); LoadHead(Head_bitmap_camera); } }else{ Log.i("camera_uri", "不为空"); ContentResolver cr = getActivity().getContentResolver(); try { InputStream in = cr.openInputStream(uri); Bitmap Head_bitmap_camera = BitmapFactory.decodeStream(in); LoadHead(Head_bitmap_camera); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } super.onActivityResult(requestCode, resultCode, data); } private void LoadHead(Bitmap head_bitmap_image) { // TODO Auto-generated method stub Person_Head.setImageBitmap(head_bitmap_image); }
此时图片已经转换成Bitmap对象,要把图片以Base64编码字符串的形式传输,还需要对Bitmap对象压缩
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //图片压缩并转换成流, //bitmap. bitmap.compress(Bitmap.CompressFormat.JPEG, 100,baos); byte[] byteServer = baos.toByteArray(); String result = Base64.encodeToString(byteServer,Base64.DEFAULT);
以上是android端的上传
然后就是服务器端的接收与转换
byte[] bt = Base64.decodeBase64(String ss); InputStream in = new ByteArrayInputStream(bt); OutputStream out1 = new FileOutputStream("F://image//b.jpg");//储存图片的地址 ByteArrayOutputStream outstream = new ByteArrayOutputStream(); byte[] by = new byte[1024]; int len = 0; while((len=in.read(by))!=-1){ outstream.write(by,0,len); } outstream.writeTo(out1);
android端的接收、服务器端的接收与返回都是流与byte[]的转换,但在不同端编解码的方式有点不同:
服务器端: 编码(字节流--->字符串):Base64.encode(byte[] input);(相关包,org.apache.catalina.util.Base64) 解码(字符串-->字节流):Base64.decodeBase64(String ss);(相关包,org.apache.tomcat.util.codec.binary.Base64) 在服务端的编解码的方法在tomcat8有效,在更早的版本,需要sun.misc.Base64Encoder和sun.misc.Base64Decoder包, Android端: 解码(字符串-->字节流):Base64.decode(String ss,Base64.DEFAULT);(相关包,android.util.Base64) 编码:需要先压缩图片,然后再转换成字节流,再编码成字符串(图片-->压缩-->字节流-->字符串) 代码如下: ByteArrayOutputStream baos = new ByteArrayOutputStream(); //图片压缩并转换成流, //bitmap. bitmap.compress(Bitmap.CompressFormat.JPEG, 100,baos); byte[] byteServer = baos.toByteArray(); String result = Base64.encodeToString(byteServer,Base64.DEFAULT);
注意事项:
在导入sun.misc.Base64Decoder等包时,系统会提示找不到,解决办法如下;
Windows -> Preferences -> Java -> Compiler -> Errors/Warnings ->
Deprecated and trstricted API -> Forbidden reference (access rules): -> change to warning
小贴士:
二进制数据要转成字符串来传输是需要经过编码(例如BASE64)处理才可以的;
1.在发送端用BASE64Encoder将二进制数据编码成字符串后再发送;
byte[] bt = <bt是读取到的图片的二制数据>;
String temp = new sun.misc.BASE64Encoder().encodeBuffer(bt);
2.在接收端用BASE64Decoder对接收到的字符串解码成二进制数据;再输出生成图片;
byte[] bt = new sun.misc.BASE64Decoder().decodeBuffer(temp);
相关文章推荐
- android自己获取并保存错误日志(可以通过邮件发送到自己邮箱)
- android camera HAL v3.0概述
- Android NDK带来什么
- android中的回调-接口回调
- 使用native程序来守护android进程
- Android开发学习笔记:Intent的简介以及属性的详解
- Android 实现手势滑动界面(ViewPager)
- SuperNotCalledException
- Android Native开发显示HTML内容
- Android中循环的几种方式
- Android ListView 点击选中效果
- 安卓入门学习(一)从布局XML到视图对象
- Android中error inflating class fragment问题
- Android App中DrawerLayout抽屉效果的菜单编写实例
- Android EditText点击其他区域收起软键盘
- 【转】Android ImageView圆形头像
- 安卓入门学习(一)用户界面设计
- Android文件上传工具类
- Viewpager和轮播图的冲突
- Android Volley完全解析