Crop image to square - Android
Asked Answered
S

4

22

How can I cut rectangular image (600 x 300) from left and right to fit in square ImageView ? I don't want to resize image, I just want to crop it, to be 300 x 300.

[SOLUTION]

As @blackbelt said

Bitmap cropImg = Bitmap.createBitmap(src, startX, startY, dstWidth, dstHeight);

is great for cropping images. So how can you automatically crop images with different sizes. I create this simple code for that:

// From drawable
Bitmap src= BitmapFactory.decodeResource(context.getResources(), R.drawable.image);

// From URL
Bitmap src = null;
try {
    String URL = "http://www.example.com/image.jpg";
    InputStream in = new java.net.URL(URL).openStream();
    src = BitmapFactory.decodeStream(in);
} catch (Exception e) {
    e.printStackTrace();
}

int width = src.getWidth();
int height = src.getHeight();
int crop = (width - height) / 2;
Bitmap cropImg = Bitmap.createBitmap(src, crop, 0, height, height);

ImageView.setImageBitmap(cropImg);
Suzettesuzi answered 8/10, 2014 at 18:14 Comment(0)
C
4

You can use

Bitmap dst = Bitmap.createBitmap(src, startX, startY, dstWidth, dstHeight);

from the documentation:

Returns an immutable bitmap from the specified subset of the source bitmap. The new bitmap may be the same object as source, or a copy may have been made. It is initialized with the same density as the original bitmap.

Here you can find the documentation

Cavell answered 8/10, 2014 at 18:19 Comment(0)
A
29

Expanding a little on the answer above

Since in some situations you can end up with an exception or not the expected result, just by using the Bitmap.createBitmap(), like the fallowing:

java.lang.IllegalArgumentException: x + width must be <= bitmap.width()

Heres is a small function that does the crop and handle some of the commons cases.

Edit: updated accordantly to droidster's claim.

public static Bitmap cropToSquare(Bitmap bitmap){
    int width  = bitmap.getWidth();
    int height = bitmap.getHeight();
    int newWidth = (height > width) ? width : height;
    int newHeight = (height > width)? height - ( height - width) : height;
    int cropW = (width - height) / 2;
    cropW = (cropW < 0)? 0: cropW;
    int cropH = (height - width) / 2;
    cropH = (cropH < 0)? 0: cropH;
    Bitmap cropImg = Bitmap.createBitmap(bitmap, cropW, cropH, newWidth, newHeight);

    return cropImg;
}

I did several testing with some images of different resolutions and sizes and it work as expected.

It can also be used in other situations, for example when you are trying to make a "perfectly" round image and need to pass a squarish bitmap, etc.

Adalbertoadalheid answered 28/2, 2015 at 15:57 Comment(2)
This is exactly what I was looking for, to get perfectly circular images and not oval. However, if the height of the image is greater than the width, doesn't crop at the centre because the value of y param is 0 in the createBitmap method. Here's how that can be fixed: Add these 2 lines: int cropH = (height - width) / 2; cropH = (cropH < 0)? 0: cropH; Use the cropH as y value. Bitmap cropImg = Bitmap.createBitmap(bitmap, cropW, cropH, newWidth, newHeight);Coincidence
Nice, I see your point.... Basically to do the same calculations for both the Width and Height.Adalbertoadalheid
G
7

set fixed image view height, width, and set two properties to image view

android:adjustViewBounds="true" 
android:scaleType="centerCrop"

done

Gallopade answered 10/9, 2016 at 6:10 Comment(0)
C
4

You can use

Bitmap dst = Bitmap.createBitmap(src, startX, startY, dstWidth, dstHeight);

from the documentation:

Returns an immutable bitmap from the specified subset of the source bitmap. The new bitmap may be the same object as source, or a copy may have been made. It is initialized with the same density as the original bitmap.

Here you can find the documentation

Cavell answered 8/10, 2014 at 18:19 Comment(0)
S
0

Now xml is having properties like

 custom:cropAspectRatioX="2"
    custom:cropAspectRatioY="1"

Make both 1 if u want square cropping. now it is of rectangle

Add activity CropActivity

       package agropost.post.agro.com.agropost.Activity;

    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.DisplayMetrics;
    import android.widget.Button;

    import com.theartofdev.edmodo.cropper.CropImageView;

    import agropost.post.agro.com.agropost.R;
    import agropost.post.agro.com.agropost.Utility.Constants;
    import butterknife.BindView;
    import butterknife.ButterKnife;
    import butterknife.OnClick;

    public class CropActivity extends AppCompatActivity {


        public static boolean isCrop = false;
        @BindView(R.id.img_crop)
        CropImageView imgCrop;
        @BindView(R.id.btn_done)
        Button btnDone;
        @BindView(R.id.btn_cancel)
        Button btnCancel;




        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_crop);
            ButterKnife.bind(this);


            DisplayMetrics displayMetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
            int width = displayMetrics.widthPixels;
            width = width - 80;
            imgCrop.getLayoutParams().height = width;
            imgCrop.getLayoutParams().width = width;

            imgCrop.setBackground(null);
            imgCrop.setScaleType(CropImageView.ScaleType.FIT_CENTER);



                imgCrop.setImageBitmap(Constants.mDashboardActivity.thumbnail_r);



        }

        @OnClick(R.id.btn_done)
        public void onViewClicked() {

            isCrop = true;
            Intent returnIntent = new Intent();



                Constants.mDashboardActivity.thumbnail_r = imgCrop.getCroppedImage();
                setResult(3, returnIntent);



            finish();
        }

        @OnClick(R.id.btn_cancel)
        public void onViewClickedCancel() {

            byte[] byteArray = getIntent().getByteArrayExtra("default");
            Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);


            Constants.mDashboardActivity.thumbnail_r = bmp;
            isCrop = true;
            Intent returnIntent = new Intent();
            setResult(3, returnIntent);

            finish();
        }


       @Override
        public void onBackPressed() {
            //  super.onBackPressed();


        }


    }

xml of activity..............

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/transparent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".Activity.CropActivity">


    <com.theartofdev.edmodo.cropper.CropImageView xmlns:custom="http://schemas.android.com/apk/res-auto"
        android:id="@+id/img_crop"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@drawable/drawer_bg"
        android:scaleType="centerInside"
        custom:cropAspectRatioX="2"
        custom:cropAspectRatioY="1"
        custom:cropFixAspectRatio="true"
        custom:cropShape="rectangle" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_done"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_marginLeft="@dimen/margin_40"
            android:layout_marginRight="@dimen/margin_20"
            android:layout_marginTop="@dimen/margin_20"
            android:layout_weight="1"
            android:background="@drawable/btn_bg_green_rounded"
            android:text="Done"
            android:textColor="@color/colorWhite"

            android:textSize="@dimen/fontsize_normal" />

        <Button
            android:id="@+id/btn_cancel"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_marginLeft="@dimen/margin_20"
            android:layout_marginRight="@dimen/margin_40"
            android:layout_marginTop="@dimen/margin_20"
            android:layout_weight="1"
            android:background="@drawable/btn_bg_green_rounded"
            android:text="Cancel"
            android:textColor="@color/colorWhite"
            android:textSize="@dimen/fontsize_normal"

            android:visibility="gone" />
    </LinearLayout>

</LinearLayout>

add dependecy

      implementation 'com.theartofdev.edmodo:android-image-cropper:2.4.+'
Sedberry answered 29/12, 2018 at 12:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.