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.
Related
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'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.
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.
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
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.