Android學習-使用Async-Http實現圖片壓縮並上傳功能

Android學習-使用Async-Http實現圖片壓縮並上傳功能

前言

(轉載請註明出處,謝謝!)

最近在作一個小項目,項目中要實現上傳圖片到服務器,而這個例子是實現圖片的尺寸壓縮,將獲取到的壓縮圖片轉爲流,而後使用Async-Http開源框架實現圖片流的上傳,而後在服務器端將流寫入本地。html

 

效果圖java

安卓端數組

服務器端安全

解決

安卓端

1、點擊加載本地相冊選擇圖片,而後加載到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();
				}

			}
		}
	}

 

2、圖片壓縮。在咱們須要上傳圖片時,咱們不可能直接把原圖上傳到服務器,由於通常圖片的大小都超過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;
		}
	}

3、將Bitmap轉爲String,同時使用BASE64加密,使傳輸更加安全,這是個人工具類,裏面再一次進行壓縮是質量壓縮,壓縮比例是30%,具體本身調。ide

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;
		}
	}

4、經過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();
				}
			});
		}

 

服務器端 


1、建立一個新的Servlet,在doget方法裏面實現post

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學習

相關文章
相關標籤/搜索