JPEG to Bitmap to JPEG - android

I tried to make a copy of an image file by first decoding the image file to Bitmap and compress it back to JPEG. The copy(~3mbs) is larger than the original file (~2mbs). Is there any way to create an exact copy?
Bitmap origBitmap = BitmapFactory.decodeFile(file);
FileOutputStream out = new FileOutputStream(file);
origBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
// this will give me a copy larger than the original image
I know I could use FileOutputStream and FileInputStream to create an identical copy. But I want to make some modification to the copy and Android doesn't support Javax.ImageIO.
FileOutputStream out = new FileOutputStream(file);
File old_file = new File(filePath);
FileInputStream input = new FileInputStream(old_file);
copyStream(input, out);
// this will give me an exact copy

JPEG is a lossy format, which means every time you use the algorithm you're losing some data. It'll look worse every time you do this, even at high quality settings.
Your copy is likely larger because you're using a quality setting of 100. I'd bet that the original file was made with a lower quality setting - usually people use between 70 and 90.

Related

Resize JPEG image in filesystem

Is there a way to resize a JPEG image file (from filesystem to filesystem) without removing meta data (just like ImageMagicks convert in.jpg -resize 50% out.jpg)?
The only way I found to resize .jpg files I found is BitmapFactory.decodeStream and Bitmap.compress, which looks like a lot of overhead if I manually need to transfer image meta data.
It may be possible to read the metadata with android.media.ExifInterface, compress the image via Bitmap.compress and then save the metadata back:
String filename = "yourfile.jpg";
// this reads all meta data
ExifInterface exif = new ExifInterface(filename);
// read and compress file
Bitmap bitmap = BitmapFactory.decodeFile(filename);
FileOutputStream fos = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
// write meta data back
exif.saveAttributes();
I didn't test it, but looking at the source code of ExifInterface, it may work.
If you don't want to rely on the implementation details, you could of course loop through all attributes and copy them.
Another solution would be to use the Android Exif Extended library. It is a small project to read and write exif data.

android image file size increased after storing

I'm using Android-Universal-Image-Loader for downloading image files from my server using .loadImageSync(imageURL) method.
And then I need to save that bitmap to user device external storage.
File file = new File(mContext.getExternalFilesDir(null) + directoryIntermediatePath, fileName);
FileOutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
My issue is .png file on my server holding size of approx 200KB, which will become approx 700KB after this process on android device storage.
You should not save the loaded image to disk. Instead you should use the file as it had been downloaded.
If I got it right the Android-Universal-Image-Loader library uses a disk cache.
If you set a specific DiskCache implementation while building the ImageLoaderConfiguration you should be able to access this DiskCache later and retrieve it later via:
File f = DiskCacheUtils.findInCache(imageURL, diskCache);
Then you only have to copy the file on byte[] level.
You can try reducing the quality parameter in bitmap.compress to some value less than 100. However, for PNG image, which is a lossless format, Bitmap will ignore the quality parameter. So, an option is to convert to JPEG for reduced size. For example, use this line:
bitmap.compress(Bitmap.CompressFormat.JPEG, 60, fileOutputStream);
For more information on bitmap.compress, check here.
If you want to reduce to a specific size using PNG, you'll have to re-scale your image; this SO link may prove useful.

Save image in internal storage without compressing

I am saving an image in storage, but the quality of image is lost due to compression. So how could I save the image without compressing it.
I'm using the following code
//Creating bitmap from Resource id
Bitmap bitmap=BitmapFactory.decodeResource(getResources(), BitmapId);
String extStorage=Environment.getExternalStorageDirectory().toString();
File file = new File(extStorage, "name.png");
if(file.exists())
file.delete();
try {
outStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
.....
}
Please let me know how to save the image without losing its quality..
The second parameter u supply 100 is actually does not affect ur image quality,but in case if u want to compress more u can reduce the value to even 10 ,u will get a low quality image in that case ,only useful for memory issues,,
But i thing the value 100 will not affect ur quality, its just a guess

Best image format for performance on itextpdf

I have got some performance problems with iText. It takes about 20 seconds to put an image into the PDF. The thing is that I have time to make those images in any format, but I should be able to add those images to PDF very quickly.
The code is for image creation is:
androidsScreenElement.setDrawingCacheEnabled(true);
androidsScreenElement.buildDrawingCache(true);
Bitmap cache = plot.getDrawingCache();
fos = new FileOutputStream("filepath.png", true);
cache.compress(Bitmap.CompressFormat.PNG, 75, fos);
fos.flush();
fos.close();
This code may run as long as it should to make optimal image for the PDF creator.
The PDF creator code is:
Document document = new Document(PageSize.A4, 30, 10, 70, 70);
PdfWriter writer = PdfWriter.getInstance(document, file);
Image image = Image.getInstance(APsFile.getAbsolutePath());
image.scalePercent(65);
image.setAlignment(Image.ALIGN_CENTER);
document.add(image);
And this is a critical part, PDF code takes too long to execute. I am wondering what an optimal image format would be. Also I cannot do caching because my android device has too litle memory already so I have to keep all 5 images in the file for before it runs the PDF generation code.

Android: Save image on SD card with its original size

When i capture an image from the camera (from the device home screen) and check the image size on the SD card, it shows between 300-500 Kb.
But when i capture an image in my Application using the Camera Intent, and save it on SD card(in a new folder) it shows image size between 5-10 Kb.
This is the code i am using to save the Image on the SD card after taking the picture in the onActivityResult:
Bitmap bit = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bao = new ByteArrayOutputStream();
bit.compress(Bitmap.CompressFormat.JPEG, 100, bao);
byte[] ba = bao.toByteArray();
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "My - Images");
File f = new File(imagesFolder, "test.jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(ba);
fo.flush();
fo.close();
how to save it as the original sized image(300-500 Kb)?
and is there a way to get the image size before i save it on the SD card??
Thank You
You are using the following to compress the bitmap object you receive:
bit.compress(Bitmap.CompressFormat.JPEG, 100, bao);
That is the reason your bitmap is being stored in a compressed format.
Also, you can use bit.getHeight() and bit.getWidth() to get the dimensions of your bitmap. You can use bit.getByteCount() to get the actual size of your bitmap
Check the answer that is accepted here, hope it may work for you
Android Camera Intent: how to get full sized photo?
Firstly try to find out the size of the picture using the code below
Camera mCamera = null;
Camera.Parameters camParams = mCamera.getParameters();
Size camSize = camParams.getPictureSize();
If the picture size you get is 5-10 KB, then there is nothing wrong with your code, you may have to re-visit your camera parameters to see what quality you have set.

Categories

Resources