Crop image to square - Android

2019-03-23 17:31发布

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);

4条回答
时光不老,我们不散
2楼-- · 2019-03-23 17:50

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.

查看更多
Emotional °昔
3楼-- · 2019-03-23 17:52

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.+'
查看更多
啃猪蹄的小仙女
4楼-- · 2019-03-23 18:03

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

查看更多
Summer. ? 凉城
5楼-- · 2019-03-23 18:07

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

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

done

查看更多
登录 后发表回答