I am converting, bitmap to jpeg using
val file = File(filePath)
val fos = FileOutputStream(file)
profileImageBitmap.compress(Bitmap.CompressFormat.JPEG,100,fos)
The jpeg looks okay. But its very tiny. I thought it was the jpeg lossy nature but when I tried to convert bitmap into png, it also came down to same size. Is there a way to increase the size of jpeg, compressed from bitmap?
You can use createScaledBitmap to scale up your bitmap before converting to jpeg, try passing true as the filter boolean to get better results. (You might want to decode the bitmap from the file first).
createScaledBitmap documentation
Related
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.
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
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.
I am trying to compress the photo took by the camera in Android. But the color of the image changed when it compressed by Bitmap.CompressFormat.JPEG. How can I solve this problem? Thanks
I have put some sample images which generated from my code. You can see the color of the paper on the top of the images is different.
Here is the code snippet:
Bitmap bitmap = BitmapFactory.decodeFile(Common.FOLDER_PATH + "pic.jpg");
FileOutputStream stream2 = new FileOutputStream(Common.FOLDER_PATH + "pic100.jpg");
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream2);
FileOutputStream stream3 = new FileOutputStream(Common.FOLDER_PATH + "pic100.png");
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream3);
This is original image:
This is JPEG:
This is PNG:
JPEG is a lossy compression format and there may be loss of image information during the compression. The sacrifice of original image information is made for a better compression ratio (resulting in smaller file).
However, if this is not acceptable for you, you should use one of the lossless compression methods which includes the PNG.
I'm trying to implement steganography on Android...but the bitmap gets compressed when it's stored, and that changes the pixel values. Is there any other way to store the image?
Thanks in advance!!
You should use a lossless compression method for your application since common compression methods with losses such as JPG will ruin your watermark data as you have checked. Taking a look at Bitmap Compression formats it seems that only JPG and PNG compression formats are available. AFAIK png
is a lossless compression method so you could use it to save your data.
FileOutputStream fos = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
Try passing 100 as maximum value of compress quality, in this way you will compress the bmp loosless.