Ashish Kumar
Ashish Kumar

Reputation: 960

Pick image from sd card, resize the image and save it back to sd card

I am working on an application, in which I need to pick an image from sd card and show it in image view. Now I want the user to decrease/increase its width by clicking a button and then save it back to the sd card.

I have done the image picking and showing it on ui. But unable to find how to resize it.Can anyone please suggest me how to achieve it.

Upvotes: 28

Views: 32861

Answers (7)

Alecs
Alecs

Reputation: 2940

Here my static method:

public static void resizeImageFile(File originalImageFile, File resizedImageFile, int maxSize) {
    Bitmap bitmap = BitmapFactory.decodeFile(originalImageFile.getAbsolutePath());
    Bitmap resizedBitmap;
    if (bitmap.getWidth() > bitmap.getHeight()) {
        resizedBitmap = Bitmap.createScaledBitmap(bitmap, maxSize, maxSize * bitmap.getHeight() / bitmap.getWidth(), false);
    } else {
        resizedBitmap = Bitmap.createScaledBitmap(bitmap, maxSize * bitmap.getWidth() / bitmap.getHeight(), maxSize, false);
    }

    FileOutputStream fileOutputStream;
    try {
        fileOutputStream = new FileOutputStream(resizedImageFile);
        resizedBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
        fileOutputStream.flush();
        fileOutputStream.close();
        bitmap.recycle();
        resizedBitmap.recycle();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Upvotes: 1

Robert Pal
Robert Pal

Reputation: 830

I found this useful library for this achievement: https://github.com/hkk595/Resizer

Upvotes: 1

Dmytro Rostopira
Dmytro Rostopira

Reputation: 11185

Solution without OutOfMemoryException in Kotlin

fun resizeImage(file: File, scaleTo: Int = 1024) {
    val bmOptions = BitmapFactory.Options()
    bmOptions.inJustDecodeBounds = true
    BitmapFactory.decodeFile(file.absolutePath, bmOptions)
    val photoW = bmOptions.outWidth
    val photoH = bmOptions.outHeight

    // Determine how much to scale down the image
    val scaleFactor = Math.min(photoW / scaleTo, photoH / scaleTo)

    bmOptions.inJustDecodeBounds = false
    bmOptions.inSampleSize = scaleFactor

    val resized = BitmapFactory.decodeFile(file.absolutePath, bmOptions) ?: return
    file.outputStream().use {
        resized.compress(Bitmap.CompressFormat.JPEG, 75, it)
        resized.recycle()
    }
}

Upvotes: 13

MAC
MAC

Reputation: 15847

Just yesterday i have done this

File dir=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
Bitmap b= BitmapFactory.decodeFile(PATH_ORIGINAL_IMAGE);
Bitmap out = Bitmap.createScaledBitmap(b, 320, 480, false);

File file = new File(dir, "resize.png");
FileOutputStream fOut;
try {
    fOut = new FileOutputStream(file);
    out.compress(Bitmap.CompressFormat.PNG, 100, fOut);
    fOut.flush();
    fOut.close();
    b.recycle();
    out.recycle();               
} catch (Exception e) {}

Also don't forget to recycle your bitmaps: It will save memory.

You can also get path of new created file String: newPath=file.getAbsolutePath();

Upvotes: 51

Dhruv Gairola
Dhruv Gairola

Reputation: 9182

You should ideally use multitouch instead of using a button to increase/decrease width. Here's an amazing library. Once the user decides to save the image, the image translation matrix must be stored persistently (in your sqlite database). Next time the user opens the image, you need to recall the matrix and apply it to your image.

I've actually done this before.

Upvotes: 0

Nermeen
Nermeen

Reputation: 15973

Try using this method:

public static Bitmap scaleBitmap(Bitmap bitmapToScale, float newWidth, float newHeight) {   
if(bitmapToScale == null)
    return null;
//get the original width and height
int width = bitmapToScale.getWidth();
int height = bitmapToScale.getHeight();
// create a matrix for the manipulation
Matrix matrix = new Matrix();

// resize the bit map
matrix.postScale(newWidth / width, newHeight / height);

// recreate the new Bitmap and set it back
return Bitmap.createBitmap(bitmapToScale, 0, 0, bitmapToScale.getWidth(), bitmapToScale.getHeight(), matrix, true);  
} 

Upvotes: 3

Related Questions