如何通过Retrofit上传未压缩的Bitmap图片?
Hey there! Let's figure out how to upload your captured Bitmap to the server without any compression using your existing code as a starting point. Here's what you need to do:
First off, your current code already successfully grabs the captured Bitmap (myBitmap) from the file path. Now we just need to extend it to send this raw, uncompressed data to your server.
1. Make Sure You're Getting the Full-Size Bitmap
Right now, BitmapFactory.decodeFile(mCurrentPhotoPath) gives you the original bitmap by default, but to be extra safe (in case you had any compression flags set elsewhere), explicitly configure the decoder to skip compression:
// Explicitly disable compression during decoding BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; // Preserve full color data Bitmap myBitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, options); click_img.setImageBitmap(myBitmap);
2. Implement the Uncompressed Upload Logic
We'll use OkHttp (a popular, reliable HTTP client) to upload the raw bitmap data. If you don't have OkHttp added to your project yet, add this dependency to your module-level build.gradle:
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
Then add this upload code right after you get myBitmap:
// Run upload in a background thread to avoid blocking the UI new Thread(new Runnable() { @Override public void run() { OkHttpClient client = new OkHttpClient(); // Convert bitmap to uncompressed PNG bytes (PNG is lossless, so no quality loss) ByteArrayOutputStream baos = new ByteArrayOutputStream(); myBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); // Quality param doesn't affect PNG, but set to 100 just in case byte[] rawBitmapBytes = baos.toByteArray(); // Build the multipart request (works with most server upload endpoints) RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("image", "captured_photo.png", RequestBody.create(MediaType.parse("image/png"), rawBitmapBytes)) // Add any extra parameters your server needs here .addFormDataPart("uploader_id", "your_user_id") .build(); Request request = new Request.Builder() .url("https://your-server.com/upload-endpoint") // Replace with your actual server URL .post(requestBody) .build(); try { Response response = client.newCall(request).execute(); // Update UI on the main thread based on result runOnUiThread(new Runnable() { @Override public void run() { if (response.isSuccessful()) { Toast.makeText(CertificationAddOwnerImage.this, "Upload successful!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(CertificationAddOwnerImage.this, "Upload failed. Try again.", Toast.LENGTH_SHORT).show(); } } }); } catch (IOException e) { e.printStackTrace(); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(CertificationAddOwnerImage.this, "Network error. Check your connection.", Toast.LENGTH_SHORT).show(); } }); } } }).start();
3. Pro Tip: Upload the Raw File Instead (Better for Memory)
If your captured photo is high-resolution, loading the full Bitmap into memory might cause an OutOfMemoryError. A better approach is to upload the original image file directly, without decoding it into a Bitmap first:
// Upload the raw captured file (no compression, no memory bloat) File rawImageFile = new File(mCurrentPhotoPath); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("image", rawImageFile.getName(), RequestBody.create(MediaType.parse("image/*"), rawImageFile)) .build();
This method sends the exact file your camera saved, with zero compression.
Quick Checks
- Make sure your app has the
INTERNETpermission inAndroidManifest.xml. - For Android 10 and below, ensure you have
WRITE_EXTERNAL_STORAGEpermission (if saving photos to external storage). For Android 11+, use scoped storage or requestMANAGE_EXTERNAL_STORAGEif needed.
内容的提问来源于stack exchange,提问作者T kumar

