5

I've been trying this for some time, I would like to create a wallpaper from a Bitmap. Let's say the desired wallpaper size is 320x480, and the source image size is 2048x2048.

I'm not sure whether crop-to-fit is the right term, but what I would like to achieve is to get most part of the picture that has the equal ratio as the desired wallpaper size (320x480).

So in this case, I would like to get 2048x1365 or (1365.333... to be exact) from the source Bitmap, and scale it down to 320x480.

The technique that I have tried is:

1) Crop the Bitmap into 2048x1365 first

bm = Bitmap.createBitmap(bm, xOffset, yOffset, 2048, 1365);

2) Scale it down to 320x480

bm = Bitmap.createScaledBitmap(bm, 320, 480, false);

which produced OutOfMemory error.

Is there any way to achieve this?

Regards,

dezull

dezull
  • 990
  • 1
  • 6
  • 18

3 Answers3

15

Thanks to open source, I found the answer from Android Gallery source code here at line 230 :-D

croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(croppedImage);

Rect srcRect = mCrop.getCropRect();
Rect dstRect = new Rect(0, 0, mOutputX, mOutputY);

int dx = (srcRect.width() - dstRect.width()) / 2;
int dy = (srcRect.height() - dstRect.height()) / 2;

// If the srcRect is too big, use the center part of it.
srcRect.inset(Math.max(0, dx), Math.max(0, dy));

// If the dstRect is too big, use the center part of it.
dstRect.inset(Math.max(0, -dx), Math.max(0, -dy));

// Draw the cropped bitmap in the center
canvas.drawBitmap(mBitmap, srcRect, dstRect, null);
dezull
  • 990
  • 1
  • 6
  • 18
  • 3
    I have your same problem. Could you explain what is mOutputX, mCrop... or better, could you write and example function than receives the bitmap and returns the cropped and scaled bitmap? Thanks a lot. – Ton Jun 07 '12 at 19:24
  • Those are the output width and height. This exact topic has been added to Android Developers site http://developer.android.com/training/displaying-bitmaps/load-bitmap.html – dezull Jun 14 '12 at 15:38
  • 1
    Basically: 1. Set srcRect to the size of the bitmap (0, 0, bitmapWidth, bitmapHeight). 2. Set dstRect to the size of your display area. 3. Execute from the "int dx" line. – Gábor Mar 31 '14 at 15:31
  • You can use my JNI solution for cropping, which avoid having 2 bitmaps at the same time : github.com/AndroidDeveloperLB/AndroidJniBitmapOperations . also I would like to ask if there is a way to avoid this all by using a customize drawable that draws only the part of the bitmap you wish to draw. – android developer May 25 '14 at 06:37
  • link is dead ! try to post content instead of links – Mayur R. Amipara Jul 16 '15 at 05:00
10

I know this is an incredibly late reply, but something like this maybe:

public static Bitmap scaleCropToFit(Bitmap original, int targetWidth, int targetHeight){
    //Need to scale the image, keeping the aspect ration first
    int width = original.getWidth();
    int height = original.getHeight();

    float widthScale = (float) targetWidth / (float) width;
    float heightScale = (float) targetHeight / (float) height;
    float scaledWidth;
    float scaledHeight;

    int startY = 0;
    int startX = 0;

    if (widthScale > heightScale) {
        scaledWidth = targetWidth;
        scaledHeight = height * widthScale;
        //crop height by...
        startY = (int) ((scaledHeight - targetHeight) / 2);
    } else {
        scaledHeight = targetHeight;
        scaledWidth = width * heightScale;
        //crop width by..
        startX = (int) ((scaledWidth - targetWidth) / 2);
    }

    Bitmap scaledBitmap = Bitmap.createScaledBitmap(original, (int) scaledWidth, (int) scaledHeight, true);

    Bitmap resizedBitmap = Bitmap.createBitmap(scaledBitmap, startX, startY, targetWidth, targetHeight);
    return resizedBitmap;
}
Daniel Jonker
  • 844
  • 10
  • 21
0

here is an answer that gets you most of the way there: How to crop an image in android?

Community
  • 1
  • 1
longhairedsi
  • 3,133
  • 2
  • 28
  • 28
  • Thanks, but not the solution I was looking for. See my own answer, just use Rect to scale it. And it doesn't produce OOM :-) – dezull Mar 08 '11 at 01:28