Compress camera image before upload

2019-01-10 08:49发布

问题:

I am using this code (from www.internetria.com) to take a photo and upload to a server:

onCreate:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri output = Uri.fromFile(new File(foto));
intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
startActivityForResult(intent, TAKE_PICTURE);

onActivityResult:

ImageView iv = (ImageView) findViewById(R.id.imageView1);
        iv.setImageBitmap(BitmapFactory.decodeFile(foto));

        File file = new File(foto);
        if (file.exists()) {
            UploaderFoto nuevaTarea = new UploaderFoto();
            nuevaTarea.execute(foto);
        }
        else
            Toast.makeText(getApplicationContext(), "No se ha realizado la foto", Toast.LENGTH_SHORT).show();

UploaderFoto:

ProgressDialog pDialog;
String miFoto = "";

@Override
protected Void doInBackground(String... params) {
    miFoto = params[0];
    try { 
        HttpClient httpclient = new DefaultHttpClient();
        httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        HttpPost httppost = new HttpPost("http://servidor.com/up.php");
        File file = new File(miFoto);
        MultipartEntity mpEntity = new MultipartEntity();
        ContentBody foto = new FileBody(file, "image/jpeg");
        mpEntity.addPart("fotoUp", foto);
        httppost.setEntity(mpEntity);
        httpclient.execute(httppost);
        httpclient.getConnectionManager().shutdown();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

And I want to compress the image, because the size is too big.

I don't know how to add bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos); to my app

回答1:

Take a look over here: ByteArrayOutputStream to a FileBody

Something along these lines should work:

replace

File file = new File(miFoto);
ContentBody foto = new FileBody(file, "image/jpeg");

with

Bitmap bmp = BitmapFactory.decodeFile(miFoto)
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 70, bos);
InputStream in = new ByteArrayInputStream(bos.toByteArray());
ContentBody foto = new InputStreamBody(in, "image/jpeg", "filename");

If file size is still an issue you may want to scale the picture in addition to compressing it.



回答2:

Convert image to Google WebP format it will save you lots of bytes see the following two articles you can also convert webP into JPG/PNG/GIF whatever you want on server side.

Java Wrapper of Google WebP API

How to check out Google WebP library and use it in Android as native library

First, you need to get pixels from Bitmap.

Bitmap bitmap = BitmapFactory.decodeFile(filePath);

int bytes = bitmap.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buffer);
byte[] pixels = buffer.array();

Then, you can get WebP byte array.

int stride = bytes / height;
int quality = 100;
byte[] encoded = libwebp.WebPEncodeRGBA(pixels, width, height, stride, quality);

Test.png (Size: 106KB) Test.webp(Size: 48KB)



回答3:

Using okhttp I upload like this:

MediaType MEDIA_TYPE_PNG
                        = MediaType.parse("image/jpeg");

                //Compress Image
                Bitmap bmp = BitmapFactory.decodeFile(fileToUpload.getAbsolutePath());
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                bmp.compress(Bitmap.CompressFormat.JPEG, 70, bos);

                RequestBody requestBody = new MultipartBuilder()
                        .type(MultipartBuilder.FORM)
                        .addFormDataPart("photo", fileToUpload.getName(), RequestBody.create(MEDIA_TYPE_PNG, bos.toByteArray()))
                        .build();

                request = new Request.Builder()
                        .url(urlToUploadTo)
                        .post(requestBody)
                        .build();

                try {
                    response = client.newCall(request).execute();
                    if (response != null) {
                        if (response.isSuccessful()) {
                            responseResult = response.body().string();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }


回答4:

Have a look at the compressImage() method:

public class MainActivity extends Activity {

private Uri fileUri;
private ImageView img_forCompress;
public static final int MEDIA_TYPE_IMAGE = 1;
private static final int CAMERA_REQUEST = 1888;
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final String IMAGE_DIRECTORY_NAME = "Ibook";
static File mediaFile;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    img_forCompress = (ImageView) findViewById(R.id.img_forCompress);

    img_forCompress.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

            intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

            // start the image capture Intent
            startActivityForResult(intent,
                    CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
        }
    });

}

public Uri getOutputMediaFileUri(int type) {
    return Uri.fromFile(getOutputMediaFile(type));
}

private static File getOutputMediaFile(int type) {

    // External sdcard location
    File mediaStorageDir = new File(
            Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            IMAGE_DIRECTORY_NAME);

    // Create the storage directory if it does not exist
    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
                    + IMAGE_DIRECTORY_NAME + " directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
            Locale.getDefault()).format(new Date());

    if (type == MEDIA_TYPE_IMAGE) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator
                + "IMG_" + timeStamp + ".jpg");
    } else {
        return null;
    }
    Log.e("path", "media file:-" + mediaFile);
    return mediaFile;
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);

    Log.e("path", "" + mediaFile.toString());
    String filename = mediaFile.toString();

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    Bitmap bitmap = BitmapFactory.decodeFile(filename, options);

    compressImage(bitmap);

}



private void compressImage(Bitmap photo) {
    // TODO Auto-generated method stub
    int imageWidth = photo.getWidth();
    int imageHeight = photo.getHeight();
    long length = mediaFile.length();
    int newHeight = 0;
    int newWidth = 0;

    Toast.makeText(MainActivity.this, "oldwidth="+imageWidth+",oldHeight="+imageHeight,Toast.LENGTH_LONG).show();
    Log.e("Old Image gheight and width---------", imageWidth + "-------"
            + imageHeight + " and Size is -- " + length);
    if (imageHeight > 1500 || imageWidth > 1500) {
        if (imageHeight > imageWidth) {
            Log.e("height is more", "true");
            newHeight = 1200;
            newWidth = (newHeight * imageWidth / imageHeight);
        }
        if (imageWidth > imageHeight) {
            Log.e("width is more", "true");
            newWidth = 1200;
            newHeight = (newWidth * imageHeight / imageWidth);
        }
    }
    Toast.makeText(MainActivity.this, "newwidth="+newWidth+",newHeight="+newHeight,Toast.LENGTH_LONG).show();
    Log.e("new Image gheight and width---------", newHeight + "-------"