最近项目上需要图片上传功能,所以开始查询相关资料,并终于实现。
android这边使用得是android studio,后台处理这边使用得是eclipse中servlet
首先是布局:(比较简单)
然后是activity
相册和拍照2种方式
final CharSequence[] items = {"相册", "拍照"};
AlertDialog.Builder dlg = new AlertDialog.Builder(UploadActivity.this);
dlg.setTitle("添加图片");
dlg.setTitle("添加图片");
dlg.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
// 这里item是根据选择的方式,
if (item == 0) {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
} else {
try {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).create();
dlg.show();
重写onActivityResult方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
// 获取游标
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imgPath = cursor.getString(columnIndex);
cursor.close();
ImageView imgView = (ImageView) findViewById(R.id.imageView);
imgView.setImageBitmap(BitmapFactory.decodeFile(imgPath));
} else if(requestCode ==0){
Bundle bundle = data.getExtras();
bitmap = (Bitmap) bundle.get("data");
ImageView imgView = (ImageView) findViewById(R.id.imageView);
imgView.setImageBitmap(bitmap);
encodeImagetoString(bitmap);
} else{
Toast.makeText(this, "You haven't picked Image",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG).show();
}
}
将图片转64编码
private void encodeImagetoString( Bitmap b) {
new AsyncTask() {
protected void onPreExecute() {
};
@Override
protected String doInBackground(Void... params) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// 压缩图片
bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream);
byte[] byte_arr = stream.toByteArray();
// Base64图片转码为String
encodedString = Base64.encodeToString(byte_arr, 0);
return "";
}
@Override
protected void onPostExecute(String msg) {
prgDialog.setMessage("Calling Upload");
// 将转换后的图片添加到上传的参数中
params.put("image", encodedString);
Toast.makeText(getApplicationContext(), encodedString.length()+"", Toast.LENGTH_LONG).show();
params.put("filename", "bbb");
// 上传图片
imageUpload();
}
}.execute(null, null, null);
}
上传图片
public void imageUpload() {
prgDialog.setMessage("Invoking JSP");
String url = AppConfig.URLS.UPLOADPIC;
AsyncHttpClient client = new AsyncHttpClient();
client.post(url, params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] bytes) {
prgDialog.hide();
Toast.makeText(getApplicationContext(), "upload success", Toast.LENGTH_LONG).show();
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] bytes, Throwable throwable) {
prgDialog.hide();
if (statusCode == 404) {
Toast.makeText(getApplicationContext(),
"Requested resource not found", Toast.LENGTH_LONG).show();
}
// 当 Http 响应码'500'
else if (statusCode == 500) {
Toast.makeText(getApplicationContext(),
"Something went wrong at server end", Toast.LENGTH_LONG).show();
}
// 当 Http 响应码 404, 500
else {
Toast.makeText(
getApplicationContext(), "Error Occured n Most Common Error: n1. Device " +
"not connected to Internetn2. Web App is not deployed in App servern3." +
" App server is not runningn HTTP Status code : "
+ statusCode, Toast.LENGTH_LONG).show();
}
}
});
}
这段代码使用到了android-async-http-1.4.8.jar,其中使用时,一个Header[]类找不到,因此,经过查询后,解决办法如下:
useLibrary 'org.apache.http.legacy' 此段代码加build.gradle到配置文件中即可
最后,这个所使用到的权限:
这样,android端就完成了,就差java后台接受上传至服务器中。
接下来是Java后台,我这里的后台在Tomcat中运行
UploadImage(servlet)
@WebServlet("/UploadImage")
public class UploadImage extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public UploadImage() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("get");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
String imgEncodedStr = request.getParameter("image");
String fileName = request.getParameter("filename");
System.out.println("Filename: "+ fileName);
// System.out.println(imgEncodedStr);
if(imgEncodedStr != null){
convertStringtoImage(imgEncodedStr, fileName);
System.out.print("Image upload complete, Please check your directory");
} else{
System.out.print("图片为空");
}
}
public void convertStringtoImage(String encodedImageStr, String fileName) {
try {
// Base64解码图片
byte[] imageByteArray = Base64.decodeBase64(encodedImageStr);
//
FileOutputStream imageOutFile = new FileOutputStream("D:/jhglpic/uploads/" + fileName+".jpg");
imageOutFile.write(imageByteArray);
imageOutFile.close();
System.out.println("成功");
} catch (FileNotFoundException fnfe) {
System.out.println("Image Path not found" + fnfe);
} catch (IOException ioe) {
System.out.println("Exception while converting the Image " + ioe);
}
}
}
这样就完成了,在测试时发现几个问题
options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; // 只获取图片的大小信息,而不是将整张图片载入在内存中,避免内存溢出
BitmapFactory.decodeFile(imgPath, options);
int inSampleSize = 2;
int height = options.outHeight;
int width= options.outWidth;
int minLen = Math.min(height, width); // 原图的最小边长
if(minLen > 100) { // 如果原始图像的最小边长大于100dp(此处单位我认为是dp,而非px)
float ratio = (float)minLen / 100.0f; // 计算像素压缩比例
inSampleSize = (int)ratio;
}
options.inJustDecodeBounds = false;
options.inSampleSize = inSampleSize; // 设置为刚才计算的压缩比例
bitmap = BitmapFactory.decodeFile(imgPath,
options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// 压缩图片
bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream);
byte[] byte_arr = stream.toByteArray();
// Base64图片转码为String
encodedString = Base64.encodeToString(byte_arr, 0);
bitmap.recycle();
最后附有 UploadActivity类