Android-图片的上传及加载

在Android端和服务器端之间,图片的传输是以经过Base64编码过的字符串进行的;

所以整个过程如下(在过程中使用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);


 

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值