user1365799
user1365799

Reputation: 83

Android camera image file size

I have a camera util class with which I take images from the camera intent, also resize the image taken.

However images taken are around 100K (After resizing), How can I make it smaller with preserving the quality. Quality needs only fo showing on the screen in the size - x,y min 320 pixels.

Here is the compression method in the class:

/*
 * quality Hint to the compressor, 0-100. 0 meaning compress for small size,
 * 100 meaning compress for max quality. Some formats, like PNG which is
 * lossless, will ignore the quality setting 
 */
private boolean c( final String i_ImageFileName, final String i_OutputImageFileName )
{
    BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();

bitmapOptions.inJustDecodeBounds = true;

try 
{
        BitmapFactory.decodeStream( new FileInputStream( i_ImageFileName ),
                                    null,
                                    bitmapOptions );
    }
catch( FileNotFoundException e ) 
{
    Log.e( mTAG, "c()- decodeStream- file not found. " + e.getMessage() );
    return false;
    }

//Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 320;
int width_tmp   = bitmapOptions.outWidth;
int height_tmp  = bitmapOptions.outHeight;
int scale       = 1;

while( true )
{
    if( width_tmp  < REQUIRED_SIZE || 
        height_tmp < REQUIRED_SIZE )
    {
        break;
    }

    width_tmp   /= 2;
    height_tmp  /= 2;
    scale       *= 2;
}

// Decode with inSampleSize
BitmapFactory.Options newBitmapOptions = new BitmapFactory.Options();

newBitmapOptions.inSampleSize=scale;

Bitmap newBitmap = null;

    newBitmap = BitmapFactory.decodeFile( /*getImageFile*/(i_ImageFileName)/*.getPath()*/ , newBitmapOptions); 

    ByteArrayOutputStream os = new ByteArrayOutputStream();

newBitmap.compress( CompressFormat.PNG, 
                        100, 
                        os );

    byte[] array = os.toByteArray();

    try 
    {
        FileOutputStream fos = new FileOutputStream(getImageFile( i_OutputImageFileName ));
        fos.write(array);
    } 
    catch( FileNotFoundException e ) 
    {
        Log.e(mTAG, "codec- FileOutputStream failed. " + e.getMessage() );
        return false;
    } 
    catch( IOException e ) 
    {
        Log.e(mTAG, "codec- FileOutputStream failed. " + e.getMessage() );
        return false;
    }

    return true;
}

I think I am doing everything "by the booK".

Upvotes: 0

Views: 1586

Answers (1)

Sean Owen
Sean Owen

Reputation: 66886

Well, of course, size and quality are two things you trade off. You can't have both smallest file size and highest quality. You are requesting highest quality here and it's too big at the right size for you. So, turn down quality.

For PNG, I don't know of the quality setting does anything (?). It is a lossless format for purposes here. (Setting to 100 might even be disabling compression, for example.)

What kinds of images are these? If they are line art, like logos (not photos), then I would be surprised if a compressed PNG is that large; that kind of image data compresses very well. (Assuming compression is on!)

For photos, it's not going to compress well. 100KB for a 320 x 320 image is about 1 byte per pixel. That's an 8-bit color table for PNG, if you get down to that file size, and 256 colors doesn't give great image quality even.

If they are photos, you want to use JPG for sure. It's far more appropriate. Even with a high quality setting, its lossy encoding should also get under 100KB easily.

Upvotes: 1

Related Questions