![](/img/trans.png)
[英]how to upload image to server without converting to Base64 in Android?
[英]Upload Large Image in Base64 to Server
我使用android.hardware.Camera
API拍照。 然后,我將其轉換為實際大小的一半的位圖,將其壓縮為質量為80的JPEG,將其轉換為Base64
並將其發送到服務器,如下所示。
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.NO_WRAP);
String json_response = "";
try {
URL url = new URL("https://example.com/api_endpoint");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write("?reg=" + regCode);
writer.write("&img=" + encoded);
writer.flush();
writer.close();
os.close();
Log.d("Auth", conn.getResponseCode() + "");
InputStreamReader in = new InputStreamReader(conn.getInputStream());
BufferedReader br = new BufferedReader(in);
String text = "";
while ((text = br.readLine()) != null) {
json_response += text;
}
conn.disconnect();
} catch (IOException e) {
Log.d(getClass().getName(), "" + e.getMessage());
}
這按預期工作。 現在,如果不調整圖像大小並保持100%的質量,應該如何避免OutOfMemoryError
? 我的應用程序要求圖像具有全分辨率和最佳質量。
我的問題是:
OutOfMemoryError
情況下發送最佳質量的圖像,即如何在此過程中優化RAM使用率? 這是我的圖像/文件上傳器類:
public class ImageUploader extends AsyncTask<String, String, String> {
File imageFile = null;
String fileName = null;
public ImageUploader(File imageFile, String fileName){
this.imageFile = imageFile;
this.fileName = fileName;
}
@Override
protected String doInBackground(String... params) {
String url_str = params[0];
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
String Tag="fSnd";
try {
URL url = new URL(url_str);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("POST");
c.setDoInput(true);
c.setDoOutput(true);
c.setRequestProperty("Connection", "Keep-Alive");
c.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
c.connect();
DataOutputStream dos = new DataOutputStream(c.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + this.fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
FileInputStream fin = new FileInputStream(imageFile);
int bytesAvailable = fin.available();
int maxBufferSize = 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[ ] buffer = new byte[bufferSize];
int bytesRead = fin.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
dos.write(buffer, 0, bufferSize);
bytesAvailable = fin.available();
bufferSize = Math.min(bytesAvailable,maxBufferSize);
bytesRead = fin.read(buffer, 0,bufferSize);
}
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
fin.close();
dos.flush();
dos.close();
StringBuilder response = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
return response.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
}
return null;
}
}
用法:
new ImageUploader(pictureFile, "sample.jpg"){
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
}.execute("http://example/upload.php");
PHP:
<?php
$file = explode('.', $_FILES['file']['name']);
$ext = $file[count($file) - 1];
$name = substr($_FILES['file']['name'], 0, (strlen($ext) + 1) * -1);
$location = 'images/';
$cntr = 1;
$tmp_name = $name;
if(move_uploaded_file($_FILES['file']['tmp_name'], $location.$tmp_name.'.'.$ext)){
echo "Image was uploaded.";
}else{
echo "Image was not uploaded.";
}
?>
如果您可以控制API端點。 然后嘗試實現POST請求,以接受來自客戶端的分段上傳。
在客戶端,使用類似的方法將圖像上傳到API(使用Okhttp客戶端)
private static final String IMGUR_CLIENT_ID = "...";
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
// Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "Square Logo")
.addFormDataPart("image", "logo-square.png",
RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
.build();
Request request = new Request.Builder()
.header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
.url("https://api.imgur.com/3/image")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
}
我認為問題不在於下載到服務器。 如果我理解正確,則可以從相機獲取圖像並將其發送。 注意,如果使用簡單的請求意圖,則返回onActivityResult()-位圖圖像 -這可能是OutOfMemoryException的問題...
解決方案是,它使用Intent()方法的另一種形式(可以在其參數中獲取存儲路徑)來從相機獲取照片,而不返回位圖圖像。 但是將照片保存到您指定的路徑。 現在,您可以對路徑中的照片執行任何操作,而無需OutOfMemoryException ...
樣本啟動正確的意圖:
File destination = new File(Environment.getExternalStorageDirectory(),
"image.jpg");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(destination));
startActivityForResult(intent, CAMERA_PICTURE);
讓我知道,這有幫助...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.