背景
Android预览相机获取相机数据流转成图片文件通过HTTP上传到服务器
方案
在AsyncTask中使用HttpURLConnection将bitmap对象上传到服务器中
项目地址:https://gitee.com/premeditate/HF21029AR-OCR.git
package org.venus.ar.ocr.net;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.venus.ar.ocr.MainActivity;
import org.venus.ar.ocr.utils.FileUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author Jxx 让世界看到我
* @Create 2022/7/7 17:19
* @Note 将摄像机获取到的图片上传到服务器进行OCR识别
*/
public class NetDetectTask extends AsyncTask<Bitmap, Boolean, List<Result>> {
private String requestUrl;
private MainActivity.OnDetectListener mDetectListener;
private long start;
public NetDetectTask(String url, MainActivity.OnDetectListener onDetectListener, long start) {
this.requestUrl = url;
this.mDetectListener = onDetectListener;
this.start = start;
}
@Override
protected List<Result> doInBackground(Bitmap... bitmaps) {
if (bitmaps == null || bitmaps.length < 1 || bitmaps[0] == null) {
return null;
}
//将bitmap转成file类型,用于上传
//定义一个图片的文件名称
String imageName = "ocr.jpg";
File file = FileUtils.bitmap2File(bitmaps[0], imageName);
if (file == null) {
System.out.println("bitmap转file失败!");
return null;
}
//创建参数列表
Map<String, String> params = new HashMap<>();
params.put("key", "value");
//定义一个上传文件的边界线
String BOUNDARY = "----WebKitFormBoundaryT1HoybnYeFOGFlBR";
StringBuilder sb = new StringBuilder();
for (String key : params.keySet()) {
sb.append("--" + BOUNDARY + "\r\n");
sb.append("Content-Disposition: form-data; name=\"" + key + "\"" + "\r\n");
sb.append("\r\n");
sb.append(params.get(key) + "\r\n");
}
//定义上传的文件的参数名称
String fileParamName = "img";
//添加请求头文件
sb.append("--" + BOUNDARY + "\r\n");
sb.append("Content-Disposition: form-data; name=\"" + fileParamName + "\"; filename=\"" + file.getName() + "\"" + "\r\n");
// 如果服务器端有文件类型的校验,必须明确指定ContentType
sb.append("Content-Type: image/jpeg" + "\r\n");
sb.append("\r\n");
HttpURLConnection conn = null;
OutputStream out = null;
InputStream in = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
byte[] headerInfo = sb.toString().getBytes("UTF-8");
byte[] endInfo = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");
//创建请求对象
URL url = new URL(requestUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
// 设置传输内容的格式,以及长度
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
conn.setRequestProperty("Content-Length", String.valueOf(headerInfo.length + file.length() + endInfo.length));
conn.setDoOutput(true);
out = conn.getOutputStream();
in = new FileInputStream(file);
// 写入头部 (包含了普通的参数,以及文件的标示等)
out.write(headerInfo);
// 写入文件
byte[] buf = new byte[1024 * 4];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
// 写入尾部
out.write(endInfo);
if (conn.getResponseCode() == 200) {
//Read
isr = new InputStreamReader(conn.getInputStream(), "UTF-8");
br = new BufferedReader(isr);
String line = null;
StringBuilder sbr = new StringBuilder();
while ((line = br.readLine()) != null) {
//System.out.println("Uploading............");
sbr.append(line);
}
String result = sbr.toString();
//System.out.println("识别结果:" + result);
try {
List<Result> data = new Gson().fromJson(result, new TypeToken<List<Result>>() {
}.getType());
return data;
} catch (Exception e) {
e.printStackTrace();
System.out.println("返回结果转换错误");
}
} else {
String responseMessage = conn.getResponseMessage();
System.out.println("网络上传失败:" + conn.getResponseCode()+"-"+responseMessage);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (conn != null) {
conn.disconnect();
}
}
return null;
}
@Override
protected void onPostExecute(List<Result> result) {
//super.onPostExecute(result);
if (mDetectListener != null) {
mDetectListener.result(result, start);
}
}
}
/**
* bitmap转file
* @param bitmap
* @param fileName
* @return
*/
public static File bitmap2File(Bitmap bitmap, String fileName){
String path = Environment.getExternalStorageDirectory() + "/bitmap2File";
File dirFile = new File(path);
if (!dirFile.exists()) {
dirFile.mkdir();
}
File myCaptureFile = new File(path + fileName);
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
return myCaptureFile;
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (bos!=null){
try {
bos.flush();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
Android中bitmap不是File文件类型,在相机的数据流中获取到的bitmap对象,需要对图像进行上传,需要先将bitmap转成File对象。
HttpURLConnection做上传请求时,将File写到请求信息中,这里需要注意的是,上传文件需要添加一个边界符属性,否则服务器接收到这个文件有错误(以前用Java写HTTP接口时没有这样操作,这次使用的是Python做HTTP服务器,还没弄明白原理)。
网友评论