30

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

David
  • 315
  • 1
  • 4
  • 8

4 Answers4

40

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.

Community
  • 1
  • 1
Matthew Wesly
  • 1,238
  • 1
  • 13
  • 14
  • InputStreamBody is deprecated. Now what? – erdomester Mar 22 '14 at 17:28
  • 7
    ContentBody foto = new ByteArrayBody(bos.toByteArray(), filename); – Sunil Kumar Jul 14 '14 at 06:50
  • this probably make OutOfMemory exception in big images. you can use this to avoid any problem : https://developer.android.com/topic/performance/graphics/load-bitmap – Amir Ziarati May 07 '18 at 11:10
  • I am also using the compress function from Bitmap but my Problem is that my Pictures look strange after compression. Maybe the reason because I'm not using a ByteArrayOutpuStream? I am using a normal Outputstream – user12346352 Aug 06 '18 at 11:37
6

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.png (Size: 106KB) Test.webp(Size: 48KB) Test.webp(Size: 48KB)

AZ_
  • 21,688
  • 25
  • 143
  • 191
2

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();
                }
user531069
  • 985
  • 8
  • 28
-2

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 + "-------"
camelCaseCoder
  • 1,447
  • 19
  • 32
Pradip
  • 315
  • 1
  • 4
  • 12