Bitmap.compress doesn't decrease the Byte count - android

I need to compress an image to send it to my server. I am trying to do it this way:
private Bitmap compressImage(Bitmap bitmapImg){
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmapImg.compress(Bitmap.CompressFormat.JPEG, 50, out);
Bitmap compressed = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
return compressed;
}
But when I compare the Byte count of the original Bitmap object and the compressed one, I get the same number:
Log.e("UNCOMPRESSED", Integer.toString(mBitmapImg.getByteCount()));
E/UNCOMPRESSED: 23970816
Log.e("COMPRESSED", Integer.toString(compressedBitmapImg.getByteCount()));
E/COMPRESSED: 23970816
How can I fix this to have a smaller file?

But when I compare the Byte count of the original Bitmap object and the compressed one, I get the same number:
The size of a Bitmap in memory is based only on its resolution (width and height in pixels) and bit depth (the number of bytes per pixel, for controlling how many colors can be used per pixel).
How can I fix this to have a smaller file?
You do not have a file. You have a Bitmap object in memory. An image file is usually stored in a compressed form. In particular, this is true for JPEG, PNG, WebP, and GIF, the four major image formats used in Android. So, for example, out.toByteArray() will be smaller than 23,970,816 bytes.
Moreover, you are not sending a Bitmap to the server. You are sending an image to the server. You need to read the documentation for the server, or talk to the server developers, to determine what image format(s) they support and how to send the image to the server (ideally, something efficient like an HTTP PUT).
If you want to reduce the in-memory size of the Bitmap, scale it to a lower-resolution image (e.g., via createScaledBitmap()).

You can change your bitmap format to RGB_565 from ARGB_8888. That'll reduce your bitmap's memory footprint to half, but, would lead to loss of quality as well. Unfortunately, that's the most you can do with Bitmap.
Having said that, the compression method that you're using should work fine for most situations. It's also the advocated method for a number of platforms. An example for Firebase is this.

Related

Android Image size after compressed from bitmap is very large than original image load to bitmap

I am now a newbie to android programming.
I am very confused when processing with images.
I am now trying to load a jpeg image to bitmap and then convert bitmap to byte array and vice versa.
I am testing with the first case: load jpeg to bitmap and get byte array.
My input image 520 x 390 (24 bit color) 24KB JPEG.
My output byte array is ~ 290000 bytes ~ 290KB, very large from the original one.
How can I convert it into byte array with the same size or nearly the same size as the original JPEG?
Therefore, I wonder if the inverse conversion will convert byte array to jpeg the same size or not ?
Here is my code:
Resources r = this.getResources();
Bitmap bm = BitmapFactory.decodeResource(r,R.drawable.plot);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,100,baos);
byte[] byteArray = baos.toByteArray();
bitmap.compress has a property of quality (the 2nd one). try reducing if from 100 to a lower number (0-100).
The JPEG you loaded is most likely to have a level of compression, which is what makes JPEGs smaller, by trading quality for size.
In your code you are setting a compression level of 100, this means no compression at all, so the bitmap is saved in JPEG format, but as it is without any size/quality reduction at all.
If you change the compression level to anything lower than 100 you will see how the file size gets smaller. Try between 80 to 90 to keep a good quality while getting a smaller file.
How can I convert it into byte array with the same size or nearly the same size as the original JPEG?
Just load the jpg file in a byte array if you need it in a byte array.
There is no need to convert to bitmap first.

How to resize and compress image with relatively good quality in Android?

So I want to limit the file size that uploaded to server, I want the image to be around 250kb with relatively good quality that uploaded to server. at the moment, I just can decrease the file size but with low quality image result.
For example, I have original jpeg image dimension 1000x1000, and it's size is 150kb. i try the reduce the width and height (in order to reduce the file size) to be 450 x 450, the file size then become 137kb, the file size just decrease little bit, but the quality is very low. I expect the quality is relatively close if just decrease from 150kb to 137kb.
I don't know how to decrease the overall file size, so I assume that I can decrease the file size by reducing the width and height to be 450x450.
here is the code I use:
after selecting image from gallery, the Uri will be transformed to be bitmap:
val originalSizeEventPosterBitmap = MediaStore.Images.Media.getBitmap(mActivity.contentResolver, eventPosterUri)
and then, I resize the bitmap to be 450x450
val resizedEventPosterBitmap = Bitmap.createScaledBitmap(originalSizeEventPosterBitmap,450,450,true)
I store the image in Firebase storage, and it requires the file transfered in ByteArray data type (it also can be transfered in Uri data type). so then I convert the bitmap from resizedEventPosterBitmap to be ByteArray first before uploading to server using the function below:
fun getBytesArrayFromBimap(image: Bitmap) : ByteArray {
val stream = ByteArrayOutputStream()
image.compress(Bitmap.CompressFormat.JPEG, 100, stream)
val bytesArrayData = stream.toByteArray()
image.recycle()
return bytesArrayData
}
the result of that function then send to server.
can You share your code or library to reduce the image size when you want to upload image to server ?
because the code I use above still make the image size quite big with low quality image

Android - Reduce image file size before upload to server with Base64

I'm trying to reduce the file size from gallery before upload to the server with base64. I've tried ALL the suggestions from stackoverflow & elsewhere I've found on the internet without success.
For images > 2MB, they seem to be reduced in size once written on the server (down to ~500KB). However, for images < 500KB they seem to be bigger than original file size once decoded and written on the server (again ~500KB). It seems like there's threshold that base64 can't get lower beyond). Is it true? Any other way I can reduce the image file size and upload to server programmatically?
private String string(Bitmap bitmap){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream);
return Base64.encodeToString(stream.toByteArray(), Base64.DEFAULT);
}
Pass bitmap into string method, to convert into String. compressFormat is in PNG which automatically lower the size and quality.

Decreasing File Size of Image From ImageView

I use the following code to obtain a bitmap from an ImageView. This image is not saved anywhere else on my device. I want to upload this image into an online mysqli database. However, to do so I need to decrease the size of the file first. I found a lot of links about this, however they all require the file to be saved on the device and then use FileOutputStream. I am looking for a way to reduce the file size so that it can be comfortably transferred using the Volley API ( i am currently receiving either run out of memory exceptions or broken pipe errors). Hence I am looking for a way to modify this code to be able to significantly decrease the file size, whilst still maintaining a quality which can be comfortably shown on a mobile device. The original image is taken straight from the camera hence the size is quite large. Here is my code:
ImageView pic_holder = (ImageView) findViewById(R.id.picturedisplay);
Bitmap bitmap = ((BitmapDrawable)pic_holder.getDrawable()).getBitmap();
ByteArrayOutputStream stream=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] image=stream.toByteArray();
String img_str = Base64.encodeToString(image, 0);
I would like to decrease the size of the img_str which is passed to my Volley method.

Android change image size before sending via HTTP [duplicate]

This question already has answers here:
Get the image as Thumbnail
(2 answers)
Closed 9 years ago.
My app is currently sending images from an Android device to a PHP script by converting the image into a bit array and then converting to base64. The base64 string is then sent in a HTTP request.
The problem is that is the image is big (like the ones taken from android camera) then the transfer fails. What i want to do is change the image size before it goes through the conversion process.
How can i do this? I've tried to google it but have had no luck so far.
If your image size is big then you have to need first scale in to small size then encode this by base64 class then you send this on your server.
For scale your image read this http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application
or other post
Use jpeg compression!
('Cause I'm not sure how sending up a base64 encoded byte array is going to save you any space.)
May I jump in and assume you've got a stage where you've converted your image into an array of pixels instead? If not, I'll assume there is no reason why the obvious conversion from bytes to integers representing pixels applies. Then we'll convert it to a compressed jpeg.
final int[] pixels = yourpixels;
You'll also need width and height:
final int width = theWidth; etc...
Next, get hold of your output stream in your client:
final HttpURLConnection connection = doWhateverYouDoToOpenYourConnection();
final OutputStream httpOutputStream = connection.getOutputStream();
Now the crucial step is to use the compression methods of Android's bitmap library to stream the compressed image onto the http output stream:
final Bitmap androidBitmap = Bitmap.createBitmap(pixels, width, height,Config.ARGB_8888);
androidBitmap.compress(android.graphics.Bitmap.CompressFormat.JPEG, YOUR_QUALITY_INT, outputStream);
Start with something like YOUR_QUALITY_INT = 85 to see significant improvement in image size without much visible deformation.
If this fails, create a scaled bitmap from a scale matrix: documentation here. This reduces the width and height of your bitmap on creation, which obviously reduces request size.
Hope this helps.

Categories

Resources