27

Possible Duplicate:
How to crop the parsed image in android?

How does one crop the same way as Androids ImageView is doing

android:scaleType="centerCrop"
Community
  • 1
  • 1
ericlee
  • 2,703
  • 11
  • 43
  • 68

1 Answers1

101

Your question is a bit short of information on what you want to accomplish, but I guess you have a Bitmap and want to scale that to a new size and that the scaling should be done as "centerCrop" works for ImageViews.

From Docs

Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding).

As far as I know, there is no one-liner to do this (please correct me, if I'm wrong), but you could write your own method to do it. The following method calculates how to scale the original bitmap to the new size and draw it centered in the resulting Bitmap.

Hope it helps!

public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) {
    int sourceWidth = source.getWidth();
    int sourceHeight = source.getHeight();

    // Compute the scaling factors to fit the new height and width, respectively.
    // To cover the final image, the final scaling will be the bigger 
    // of these two.
    float xScale = (float) newWidth / sourceWidth;
    float yScale = (float) newHeight / sourceHeight;
    float scale = Math.max(xScale, yScale);

    // Now get the size of the source bitmap when scaled
    float scaledWidth = scale * sourceWidth;
    float scaledHeight = scale * sourceHeight;

    // Let's find out the upper left coordinates if the scaled bitmap
    // should be centered in the new size give by the parameters
    float left = (newWidth - scaledWidth) / 2;
    float top = (newHeight - scaledHeight) / 2;

    // The target rectangle for the new, scaled version of the source bitmap will now
    // be
    RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);

    // Finally, we create a new bitmap of the specified size and draw our new,
    // scaled bitmap onto it.
    Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
    Canvas canvas = new Canvas(dest);
    canvas.drawBitmap(source, null, targetRect, null);

    return dest;
}
Kumar KL
  • 15,315
  • 9
  • 38
  • 60
Albin
  • 4,180
  • 2
  • 27
  • 19
  • hi, may i know how do i give it a white border from this bitmap? – ericlee Nov 13 '11 at 19:32
  • Do you want a white border on top of the scaled bitmap or do you want a white border, like padding, around it? – Albin Nov 13 '11 at 19:43
  • @ericlee that's a new question. – StackOverflowed Jul 22 '12 at 20:30
  • I have tried this.But resulted image quality is very rough. I think cropped image is small then image is scaling so image stretching so much. Can u tell me how make crop frame little bit large? – Akanksha Rathore Jan 15 '14 at 09:38
  • cutting corners in cropping from top and bottom for this which parameter i have to change in this line = RectF(left, top, left + scaledWidth, top + scaledHeight); – Akanksha Rathore Jan 15 '14 at 11:53
  • The code was meant to scale the image as if ImageView.ScaleType.CENTER_CROP was used. If the original image is smaller than the new width and/or height, it will be enlarged, which could result in blockiness. If you want to avoid scaling up small images, you could add a line with 'if (scale > 1) scale = 1;' just after computing scale. This will only scale down images, while smaller images will be centered within the new rectangle. Does that answer your question? – Albin Jan 15 '14 at 15:19
  • @Albin: How to do `ScaleType.centerInside` ? – Mehul Joisar Apr 11 '14 at 12:15
  • @MehulJoisar: Without trying it out, I think it's sufficient to change Math.max to Math.min in the code above. – Albin Apr 15 '14 at 08:52
  • 8
    Another alternative: ThumbnailUtils.extractThumbnail(bitmap,width, height); – android developer May 22 '14 at 12:01
  • This is what I exactly wanted. – Narendra Singh May 21 '15 at 10:56
  • 10 plus for this answer, thank you!! – Mohad Hadi Jun 05 '16 at 16:00
  • this solution works fine for low resolution phones, but for hight resolution it crops bigger part of image, scaledwith and scaledheight seems too large – Nininea Nov 25 '16 at 22:06
  • any update about hight resolution devices? – Nininea Nov 25 '16 at 22:08
  • @Nininea Could you give an example of sizes where you have a problem? Preferably both source and target sizes. Unfortunately I don't really do Android development anymore, but it should be easy to test if rounding or overflow are issues. – Albin Nov 28 '16 at 08:35
  • for example, I'm testing it in my nexus 5 , source bit map size was : 3268 X 2448 and I wanted to crop in center 600X600 photo, but with this algorithm crops bigger rectangle, (shows more content than it should do) – Nininea Nov 28 '16 at 11:43
  • @Nininea I looked through the numbers. The result should be that the left and right side are cropped away (410px from each side) to a square 2448x2448 image. Then it is resized to 600x600. In what way do you see more content than this? There should be no rounding issues with numbers of that magnitude. – Albin Nov 28 '16 at 19:50
  • @Albin how you calculated 410 px from left and right? For me left is -100 and top is 0 – Nininea Nov 28 '16 at 20:22
  • @Nininea Sorry. I did cropping first and resizing afterwards and that's not how the code is written. Following the code it would resize the original to approximately 800x600 and then cut away 100px on the right and left sides each to end up with a 600x600 bitmap. Does that makes sense? – Albin Nov 29 '16 at 09:56
  • thx...mate for your code – Amaresh Jana Jun 08 '17 at 12:15
  • This is perfect!!! Thank you.. – Hitesh Bisht Nov 12 '18 at 17:20