70

How can i crop a bitmap image? this is my question i have tried some concepts using intents but still fail..

I am having a bitmap image which i want to crop!!

here is the code :

 Intent intent = new Intent("com.android.camera.action.CROP");  
                      intent.setClassName("com.android.camera", "com.android.camera.CropImage");  
                      File file = new File(filePath);  
                      Uri uri = Uri.fromFile(file);  
                      intent.setData(uri);  
                      intent.putExtra("crop", "true");  
                      intent.putExtra("aspectX", 1);  
                      intent.putExtra("aspectY", 1);  
                      intent.putExtra("outputX", 96);  
                      intent.putExtra("outputY", 96);  
                      intent.putExtra("noFaceDetection", true);  
                      intent.putExtra("return-data", true);                                  
                      startActivityForResult(intent, REQUEST_CROP_ICON);

Could anybody help me regarding this @Thanks

Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
  • Take a look on this tutorial: http://mobile.tutsplus.com/tutorials/android/capture-and-crop-an-image-with-the-device-camera/ – Dmytro Danylyk Apr 03 '13 at 13:48
  • @DmytroDanylyk thanks for your response..let me check!! –  Apr 03 '13 at 13:49
  • @DmytroDanylyk its also the same thing.. intent.setData(bitmap);is not working –  Apr 03 '13 at 13:51
  • Which device re you using? Maybe it would be better to crop bitmap, after camera return it to you. Here is link how to properly crop it: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html – Dmytro Danylyk Apr 03 '13 at 14:14
  • Kindly check this link which works for me https://stackoverflow.com/a/63801992/6631601 – Hantash Nadeem Sep 08 '20 at 22:05

6 Answers6

170

I used this method to crop the image and it works perfect:

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.xyz);

Bitmap resizedBmp = Bitmap.createBitmap(bmp, 0, 0, yourwidth, yourheight);

createBitmap() takes bitmap, start X, start Y, width & height as parameters.

hata
  • 11,633
  • 6
  • 46
  • 69
sankettt
  • 2,387
  • 4
  • 23
  • 31
  • 1
    sankettt what about yourwidth,yourheight; could you explain in brief –  Apr 03 '13 at 14:20
  • 1
    @priya2134412 sure. its the width and height of the amount of bitmap you want to crop.i.e the part you want to crop – sankettt Apr 03 '13 at 14:23
  • sankettt shall i have to use any class!! –  Apr 03 '13 at 14:26
  • 1
    Nope just use it directly and the resizedbitmap where ever you want to.I used this code to do frame animation by cutting the image into several section and loading each section in a frame – sankettt Apr 03 '13 at 14:29
  • sankettt i have a doubt suppose user need to scale the image then this coding will use –  Apr 03 '13 at 14:30
  • If user needs to scale the image then one thing can be done is that the width and height ur specifying should be in terms of width and height of screen.like width*0.15 . – sankettt Apr 03 '13 at 14:33
  • use this code if you want to maintain aspect ration of image public static int getAspectY(float dimensionX,float dimensionY,int aspectX) { float r=dimensionY/dimensionX; return Math.round(r * aspectX); } – Nandan Singh Dec 17 '15 at 12:09
  • 2
    Is there a way to crop the bitmap, yet the output bitmap would be of a certain size, without creating another bitmap ? – android developer Aug 29 '17 at 16:40
15

Using the answer above does not work if you want to slice/crop areas particular out of bounds! Using this code you will always get your desired size - even if the source is smaller.

//  Here I want to slice a piece "out of bounds" starting at -50, -25
//  Given an endposition of 150, 75 you will get a result of 200x100px
Rect rect = new Rect(-50, -25, 150, 75);  
//  Be sure that there is at least 1px to slice.
assert(rect.left < rect.right && rect.top < rect.bottom);
//  Create our resulting image (150--50),(75--25) = 200x100px
Bitmap resultBmp = Bitmap.createBitmap(rect.right-rect.left, rect.bottom-rect.top, Bitmap.Config.ARGB_8888);
//  draw source bitmap into resulting image at given position:
new Canvas(resultBmp).drawBitmap(bmp, -rect.left, -rect.top, null);

...and you're done!

coyer
  • 4,122
  • 3
  • 28
  • 35
  • What's the result here exactly, of cropping outside of the bounds? What's in the result bitmap? Part of it is transparent? – android developer Dec 28 '21 at 19:49
  • I wrote that code as a magnifierfunction to zoom into images. That magnifier should have always the same size which other solutions here does not. `resultBmp` can be filled with a transparent background or any desired color before the last line would draw the cropped image to it. So there might be a transparent background if, for example, the center of the magnifier is the most upper left pixel of the source image. – coyer Dec 29 '21 at 06:52
  • It's not quite cropping then, because a part of the result might not be a part of the input bitmap. It's still a nice thing though that could be useful. – android developer Dec 29 '21 at 07:22
3

I had similar problem with cropping and after trying numerous approaches I figured out this one which made sense to me. This method only crops the image to square shape, I am still working on the circular shape (Feel free to modify the code to get shape you need).

So, first you have yout bitmap that you want to crop:

Bitmap image; //you need to initialize it in your code first of course

The image information is stored in an int [ ] array what is nothing more than an array of integers containing the color value of each pixel, starting at the top left corner of the image with index 0 and ending at the bottom right corner with index N. You can obtain this array with Bitmap.getPixels() method which takes various arguments.

We need the square shape, therefore we need to shorten the longer of the sides. Also, to keep the image centered the cropping needs to be done at the both sides of the image. Hopefully the image will help you understand what I mean. Visual representation of the cropping. The red dots in the image represent the initial and final pixels that we need and the variable with the dash is numerically equal to the same variable without the dash.

Now finally the code:

int imageHeight = image.getHeight(); //get original image height
int imageWidth = image.getWidth();  //get original image width
int offset = 0;

int shorterSide = imageWidth < imageHeight ? imageWidth : imageHeight;
int longerSide = imageWidth < imageHeight ? imageHeight : imageWidth;
boolean portrait = imageWidth < imageHeight ? true : false;  //find out the image orientation
//number array positions to allocate for one row of the pixels (+ some blanks - explained in the Bitmap.getPixels() documentation)
int stride = shorterSide + 1; 
int lengthToCrop = (longerSide - shorterSide) / 2; //number of pixel to remove from each side 
//size of the array to hold the pixels (amount of pixels) + (amount of strides after every line)
int pixelArraySize = (shorterSide * shorterSide) + (shorterImageDimension * 1);
int pixels = new int[pixelArraySize];

//now fill the pixels with the selected range 
image.getPixels(pixels, 0, stride, portrait ? 0 : lengthToCrop, portrait ? lengthToCrop : 0, shorterSide, shorterSide);

//save memory
image.recycle();

//create new bitmap to contain the cropped pixels
Bitmap croppedBitmap = Bitmap.createBitmap(shorterSide, shorterSide, Bitmap.Config.ARGB_4444);
croppedBitmap.setPixels(pixels, offset, 0, 0, shorterSide, shorterSide);

//I'd recommend to perform these kind of operations on worker thread
listener.imageCropped(croppedBitmap);

//Or if you like to live dangerously
return croppedBitmap;
1

For cropping bitmap with given width from left and right side simply use this code

int totalCropWidth = "your total crop width"; int cropingSize = totalCropWidth / 2; Bitmap croppedBitmap = Bitmap.createBitmap(yourSourceBitmap, cropingSize ,0,yourSourceBitmapwidth-totalCropWidth , yourheight);

Vajani Kishan
  • 293
  • 4
  • 13
0

I extend @sankettt's method, when you want to scale down a large bitmap and crop it fit with your ImageView size

use this method:

/**
 * crop a img with new expected size
 * @param src
 * @param newSize
 * @return
 */
public static Bitmap scaleAndGenerateBmpWithNewSize(Bitmap src, SizeManager newSize) {
    Bitmap bitmapRes;
    int imageWidth = src.getWidth();
    int imageHeight = src.getHeight();

    float newWidth = newSize.width;
    float scaleFactor = newWidth / imageWidth;
    int newHeight = (int) (imageHeight * scaleFactor);
    bitmapRes = Bitmap.createScaledBitmap(src, (int) newWidth, newHeight, true);
    bitmapRes = Bitmap.createBitmap(bitmapRes, 0, 0, (int) newWidth, (int) newSize.height);
    return bitmapRes;
}

SizeManager class:

public class SizeManager {
    public float width;
    public float height;

    public SizeManager() {
    }

    public SizeManager(float width, float height) {
        this.width = width;
        this.height = height;
    }

    public void set(float width, float height) {
        this.width = width;
        this.height = height;
    }

    public float getWidth() {
        return width;
    }

    public void setWidth(float width) {
        this.width = width;
    }

    public float getHeight() {
        return height;
    }

    public void setHeight(float height) {
        this.height = height;
    }
}

Usage:

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.src);
imgView.setImageBitmap(scaleAndGenerateBmpWithNewSize(bitmap, new SizeManager(100, 100)));
dotrinh PM
  • 903
  • 1
  • 7
  • 19
0

If you have a rect this,

Rect f = barcode.getBoundingBox();
Bitmap.createBitmap(bmp,f.left,f.top,f.width(),f.height());

Bitmap.createBitmap takes (bitmap,left,top,width,height)// make sure none of the value is negative and not exceeding the image area

Satheesh
  • 1,252
  • 11
  • 11