在尝试制作圆形位图时,背景保持正方形

时间:2017-02-15 16:18:15

标签: java android android-studio android-bitmap

所以我现在正在尝试大约一个星期来让这件事工作但无济于事......

我希望用户从他的画廊中挑选一张图片,然后将该图片裁剪成一张漂亮的圆形个人照片,我会将照片裁剪成裁剪,但背景仍然是正方形......我发现了这个问题并试图实现答案他给了但背景却是正方形Cropping circular area from bitmap in Android

我用谷歌搜索,发现了更多的方法,但仍然得到了方形背景......任何帮助将不胜感激

public class RegisterActivity extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    private String mParam1;
    private String mParam2;

    RoundedImageView roundImageView ;
    String numberToPass = "1";//default 1 for male
    String selectedImagePath;
    EditText etNickname, etAge;
    Button btnNext;
    ImageView profilePhoto, imageview;
    Bitmap bitmap;



    private OnRegisterListener mListener;

    public RegisterActivity() {
        // Required empty public constructor
    }

    public static RegisterActivity newInstance(String param1, String param2) {
        RegisterActivity fragment = new RegisterActivity();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_register, container, false);
        etNickname = (EditText) view.findViewById(R.id.etNickName);
        btnNext = (Button) view.findViewById(R.id.btnNextRegister);
        profilePhoto = (ImageView) view.findViewById(R.id.imageButton);
        bitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.blender);
       // profilePhoto.setImageBitmap(bitmap);

       /*   Bitmap bitmap2 = BitmapFactory.decodeResource(this.getResources(),R.drawable.blender);
        Bitmap circularBitmap = ImageConverter.getRoundedCornerBitmap(bitmap2, 100);
        ImageView circularImageView = (ImageView)view.findViewById(R.id.imageButton);
        circularImageView.setImageBitmap(circularBitmap);     */


        profilePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openGallery();
            }
        });


        return view;
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnRegisterListener) {
            mListener = (OnRegisterListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnRegisterListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }


    public interface OnRegisterListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }

    //this allows the uset to select one image from openGallery
    public void openGallery() {
        Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
        startActivityForResult(gallery, 1);
    }

    //when  starting activity for result and choose an image, the code will automatically continue here
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && requestCode == 1 && null != data) {
            if (requestCode == 1) {
                Uri current_ImageURI = data.getData();

                /* String[] filePathColumn = { MediaStore.Images.Media.DATA };

                Cursor cursor = getActivity().getContentResolver().query(current_ImageURI,
                        filePathColumn, null, null, null);
                cursor.moveToFirst();

                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String picturePath = cursor.getString(columnIndex);
                cursor.close();*/

                selectedImagePath = getPath(current_ImageURI);
                profilePhoto.setImageBitmap(circleBitmap(decodeSampledBitmap(new File(selectedImagePath), 250, 250)));

            }
        }
    }


    public String getPath(Uri contentUri) {
        // we have to check for sdk version because from lollipop the retrieval of path is different
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // can post image
            String[] proj = {MediaStore.Images.Media.DATA};
            Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(contentUri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();

            return cursor.getString(column_index);
        } else {
            String filePath = "";
            String wholeID = DocumentsContract.getDocumentId(contentUri);

            // Split at colon, use second item in the array
            String id = wholeID.split(":")[1];

            String[] column = {MediaStore.Images.Media.DATA};

            // where id is equal to
            String sel = MediaStore.Images.Media._ID + "=?";

            Cursor cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{id}, null);

            int columnIndex = cursor.getColumnIndex(column[0]);

            if (cursor.moveToFirst()) {
                filePath = cursor.getString(columnIndex);
            }
            cursor.close();
            return filePath;
        }
    }

    public Bitmap decodeSampledBitmap(File res, int reqWidth, int reqHeight) {
        if (res != null) {
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            try {
                FileInputStream stream2 = null;
                try {
                    stream2 = new FileInputStream(res);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }

                BitmapFactory.decodeStream(stream2, null, options);

                stream2.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // Calculate inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            o2.inJustDecodeBounds = false;
            FileInputStream stream = null;
            try {
                stream = new FileInputStream(res);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            Bitmap bitmap = BitmapFactory.decodeStream(stream, null, o2);
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bitmap;
        } else
            return null;
    }

    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }



    //-----------------------------------------------------------------
    private Bitmap circleBitmap(Bitmap bitmap) {
        final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        int squareBitmapWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());

           /* Canvas
                The Canvas class holds the "draw" calls. To draw something, you need 4 basic
                components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing
                into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint
                (to describe the colors and styles for the drawing).  */

        final Canvas canvas = new Canvas(output);

        final int color = Color.RED;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        // final Rect rect = new Rect(0, 0, squareBitmapWidth, squareBitmapWidth);

        final RectF rectF = new RectF(rect);

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
        //canvas.drawOval(rectF, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //float left = (squareBitmapWidth - bitmap.getWidth()) / 2;
        //float top = (squareBitmapWidth - bitmap.getHeight()) / 2;
        //canvas.drawBitmap(bitmap, left, top, paint);
        canvas.drawBitmap(bitmap, rect, rect, paint);
        //bitmap.recycle();
        return output;
    }

    //---------------------------------------------------------------------------------------------
    //end img upload

3 个答案:

答案 0 :(得分:0)

我使用此代码并且效果很好:

public static Bitmap getCircularBitmap(Bitmap bitmap) {
    Bitmap output;

    if (bitmap.getWidth() > bitmap.getHeight()) {
        output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    } else {
        output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
    }

    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

    float r = 0;

    if (bitmap.getWidth() > bitmap.getHeight()) {
        r = bitmap.getHeight() / 2;
    } else {
        r = bitmap.getWidth() / 2;
    }

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawCircle(r, r, r, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);
    return output;
}

答案 1 :(得分:0)

您可以自定义ImageView使其所有绘图内容循环播放。这是我的实现(不是性能急切应用的最佳解决方案,但对于不会使ImageView无效的条件足够好):

class CircleImageView extends ImageView {

    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    public CircleImageView(Context context) {
        super(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int radiusMeasureSpec = widthMeasureSpec;
        super.onMeasure(radiusMeasureSpec, radiusMeasureSpec);
        int radiusMeasureSize = MeasureSpec.getSize(widthMeasureSpec);
        setMeasuredDimension(radiusMeasureSize, radiusMeasureSize);
    }

    @Override
    public void draw(Canvas viewCanvas) {
        final int EDGE_SIZE = viewCanvas.getWidth();

        // Draw this View's things.
        Bitmap fgBm = Bitmap.createBitmap(EDGE_SIZE, EDGE_SIZE, Bitmap.Config.ARGB_8888);
        Canvas fgCanvas = new Canvas(fgBm);
        super.draw(fgCanvas);

        // Transfer to a special shape.
        Bitmap shapedBm = Bitmap.createBitmap(EDGE_SIZE, EDGE_SIZE, Bitmap.Config.ARGB_8888);
        Canvas shapedCanvas = new Canvas(shapedBm);
        shapedCanvas.drawCircle(EDGE_SIZE/2, EDGE_SIZE/2, EDGE_SIZE/2, mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        shapedCanvas.drawBitmap(fgBm, 0, 0, mPaint);
        mPaint.setXfermode(null);

        // Move drawn things to View's canvas.
        viewCanvas.drawBitmap(shapedBm, 0, 0, mPaint);
        fgBm.recycle();
        shapedBm.recycle();
    }

}

有人在SO post中使用ImageView自定义BitmapShader而没有Xfermode,并创建额外的Bitmap个实例。这是his implementation

答案 2 :(得分:0)

您可以使用This之类的受信任库 添加圆形图像为图像添加边框和其他一些功能