it-swarm.dev

كيفية إضافة الظل والحدود على صورة دائريةعرض الروبوت؟

لقد قمت بإنشاء CircularImageView مع هذا السؤال: إنشاء طريقة عرض صورة دائرية في Android

تنزيل المشروع على GitHub

1) هذه هي الفئة CircularImageView:

public class CircularImageView extends ImageView {
    public CircularImageView(Context context) {
        super(context);
    }

    public CircularImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return; 
        }
        Bitmap b =  ((BitmapDrawable)drawable).getBitmap() ;
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);      

        Bitmap roundBitmap =  getCroppedBitmap(bitmap, getWidth());
        canvas.drawBitmap(roundBitmap, 0, 0, null);
    }

    public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
        Bitmap sbmp;
        if(bmp.getWidth() != radius || bmp.getHeight() != radius)
            sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
        else
            sbmp = bmp;

        Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(), Bitmap.Config.ARGB_8888);
        final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());

        Paint paint = new Paint();
        Paint.setAntiAlias(true);
        Paint.setFilterBitmap(true);
        Paint.setDither(true);      
        Paint.setColor(Color.parseColor("#BAB399"));

        Canvas c = new Canvas(output);        
        c.drawARGB(0, 0, 0, 0);
        c.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f, sbmp.getWidth() / 2+0.1f, Paint);
        Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        c.drawBitmap(sbmp, rect, rect, Paint);

        return output;
    }
}

2) أنا استخدم في تخطيط بلدي مثل هذا:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="#cccccc"
    Android:gravity="center"
    Android:orientation="vertical"
    Android:padding="10dp" >

    <com.mikhaellopez.circularimageview.CircularImageView
        Android:id="@+id/imageViewCircular"
        Android:layout_width="@dimen/image_view_size"
        Android:layout_height="@dimen/image_view_size"
        Android:layout_gravity="center"
        Android:background="@drawable/border"
        Android:src="@drawable/image" />

</LinearLayout>

3) النتيجة الحالية في الصورة:

Current result

كيف يمكنني تغيير هذا الرمز ليكون له حد دائري حول imageView الخاص بي؟

النتيجة الموضوعية:

Objectif result


تحرير 10/15/2015:

يمكنك استخدام أو تنزيل my مكتبة GitHub CircularImageView with جميع الإصلاحات باستخدام اعتماد التبعية :

compile 'com.mikhaellopez:circularimageview:2.0.1'
59
lopez.mikhael

لقد عدلت CircularImageView وجدت هنا لتحقيق ما تريد.

لإنشاء ظل حول الحدود ، استخدمت ببساطة هذين السطرين:

this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);

تحتاج إلى setLayerType بسبب تسريع الأجهزة على HoneyComb وما فوق. لم تنجح بدونها عندما جربتها.

هنا هو الكود الكامل:

import Android.annotation.SuppressLint;
import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.BitmapShader;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.Shader;
import Android.graphics.drawable.BitmapDrawable;
import Android.util.AttributeSet;
import Android.widget.ImageView;

public class CircularImageView extends ImageView
{
    private int borderWidth = 4;
    private int viewWidth;
    private int viewHeight;
    private Bitmap image;
    private Paint paint;
    private Paint paintBorder;
    private BitmapShader shader;

    public CircularImageView(Context context)
    {
        super(context);
        setup();
    }

    public CircularImageView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        setup();
    }

    public CircularImageView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        setup();
    }

    private void setup()
    {
        // init Paint
        Paint = new Paint();
        Paint.setAntiAlias(true);

        paintBorder = new Paint();
        setBorderColor(Color.WHITE);
        paintBorder.setAntiAlias(true);
        this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
        paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
    }

    public void setBorderWidth(int borderWidth)
    {
        this.borderWidth = borderWidth;
        this.invalidate();
    }

    public void setBorderColor(int borderColor)
    {
        if (paintBorder != null)
            paintBorder.setColor(borderColor);

        this.invalidate();
    }

    private void loadBitmap()
    {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();

        if (bitmapDrawable != null)
            image = bitmapDrawable.getBitmap();
    }

    @SuppressLint("DrawAllocation")
    @Override
    public void onDraw(Canvas canvas)
    {
        // load the bitmap
        loadBitmap();

        // init shader
        if (image != null)
        {
            shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            Paint.setShader(shader);
            int circleCenter = viewWidth / 2;

            // circleCenter is the x or y of the view's center
            // radius is the radius in pixels of the cirle to be drawn
            // Paint contains the shader that will texture the shape
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - 4.0f, paintBorder);
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - 4.0f, Paint);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec, widthMeasureSpec);

        viewWidth = width - (borderWidth * 2);
        viewHeight = height - (borderWidth * 2);

        setMeasuredDimension(width, height);
    }

    private int measureWidth(int measureSpec)
    {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY)
        {
            // We were told how big to be
            result = specSize;
        }
        else
        {
            // Measure the text
            result = viewWidth;
        }

        return result;
    }

    private int measureHeight(int measureSpecHeight, int measureSpecWidth)
    {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpecHeight);
        int specSize = MeasureSpec.getSize(measureSpecHeight);

        if (specMode == MeasureSpec.EXACTLY)
        {
            // We were told how big to be
            result = specSize;
        }
        else
        {
            // Measure the text (beware: ascent is a negative number)
            result = viewHeight;
        }

        return (result + 2);
    }
}

اتمني ان يكون مفيدا!

.

EDIT

لقد متشعب CircularImageView الخاص بك وإضافة دعم لتراكب محدد. أنا أيضا تحسين أداء الرسم بشكل كبير ...

https://github.com/Pkmmte/CircularImageView

72
Pkmmte

لإضافة حد عن طريق جعل ImageView كدائرة ، لقد فعلت شيئًا بسيطًا ، واستخدمت هذه الفئة لجعل صورتي كدائرة

package com.fidenz.fexceller.fexceller;

/**
 * Created by Chathu Hettiarachchi on 5/18/2015.
 */
import Android.graphics.Bitmap;
import Android.graphics.BitmapShader;
import Android.graphics.Canvas;
import Android.graphics.ColorFilter;
import Android.graphics.Paint;
import Android.graphics.PixelFormat;
import Android.graphics.Rect;
import Android.graphics.RectF;
import Android.graphics.Shader;
import Android.graphics.drawable.Drawable;

public class RoundedImg extends Drawable {
    private final Bitmap mBitmap;
    private final Paint mPaint;
    private final RectF mRectF;
    private final int mBitmapWidth;
    private final int mBitmapHeight;

    public RoundedImg(Bitmap bitmap) {
        mBitmap = bitmap;
        mRectF = new RectF();
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mPaint.setShader(shader);

        mBitmapWidth = mBitmap.getWidth();
        mBitmapHeight = mBitmap.getHeight();
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawOval(mRectF, mPaint);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        mRectF.set(bounds);
    }

    @Override
    public void setAlpha(int alpha) {
        if (mPaint.getAlpha() != alpha) {
            mPaint.setAlpha(alpha);
            invalidateSelf();
        }
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public int getIntrinsicWidth() {
        return mBitmapWidth;
    }

    @Override
    public int getIntrinsicHeight() {
        return mBitmapHeight;
    }

    public void setAntiAlias(boolean aa) {
        mPaint.setAntiAlias(aa);
        invalidateSelf();
    }

    @Override
    public void setFilterBitmap(boolean filter) {
        mPaint.setFilterBitmap(filter);
        invalidateSelf();
    }

    @Override
    public void setDither(boolean dither) {
        mPaint.setDither(dither);
        invalidateSelf();
    }

    public Bitmap getBitmap() {
        return mBitmap;
    }

}

وباستخدام هذا على onCreate ، أتصل بالصورة لتعيينها ،

profilePic = (ImageView)findViewById(R.id.img_home_profile_pic);

Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.no_image);
roundedImage = new RoundedImg(bm);
profilePic.setImageDrawable(roundedImage);

لإضافة حد قمت بإنشاء XML شكل دائرة مثل هذا ،

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="oval" >
    <gradient Android:startColor="@color/ring_color" Android:endColor="@color/ring_color"
        Android:angle="270"/>
</shape>

ثم باستخدام تخطيطات أضفت RelativeLayout مع ImageView داخله ، باستخدام الحشوة والخلفية القابلة للرسم مع wrap_content أضع RelativeLayout مثل هذا

<RelativeLayout
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:id="@+id/lay_rel_img"
    Android:layout_gravity="center"
    Android:padding="5dp"
    Android:background="@drawable/circle">

    <ImageView
        Android:layout_width="150dp"
        Android:layout_height="150dp"
        Android:layout_gravity="center"
        Android:id="@+id/img_home_profile_pic"
        Android:src="@drawable/no_image"
        Android:layout_centerHorizontal="true"/>

</RelativeLayout>

الآن يظهر مثل هذا ، أنا لا أعرف لإضافة الظل ، آسف لذلك أيضًا

enter image description here

10
Chathura Jayanath
  1. أضف canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, Paint); قبل canvas.drawBitmap(roundBitmap, 0, 0, null);
  2. تغيير c.drawCircle(sbmp.getWidth() / 2, sbmp.getHeight() / 2, sbmp.getWidth() / 2, Paint); إلى c.drawCircle(sbmp.getWidth() / 2, sbmp.getHeight() / 2, sbmp.getWidth() / 2 - "the border with you prefer", Paint);

آمل أن يساعد.

ربما حل أفضل هنا .

3
cycDroid

قم بإنشاء درج مخصص ، واستخدمه لتعريف السمة الخلفية لبرنامج ImageView الخاص بك. يمكنك استخدام LayeredDrawable ، لإنشاء العديد من المكونات المختلفة للمكون كما تريد.

اطلع على هذه الإجابة ، والتي تنشئ مستطيلًا مخصصًا (ولكن هو نفسه تمامًا مع Oval\Circle): كيفية إنشاء بطاقات واجهة مستخدم + Google في عرض قائمة؟

3
Booger

لقد وجدت مكتبة تفعل ما تشاء بالضبط ، عملت بشكل جيد بالنسبة لي. تحقق من ذلك. https://Android-arsenal.com/details/1/932

2
daniel kilinskas

فقط استخدم طريقة drawCircle () بمزيد من العرض والارتفاع قبل رسم الصورة الفعلية. قم بزيادة عرض وارتفاع هذه المكالمة بالطريقة الجديدة وفقًا لرغبتك ، واضبط بعض الألوان الأخرى التي تريدها على الرسام

1
Onur A.

هذه الفئة هي صورة دائرية مخصصة مع ظل ، حد ، تشبع واستخدام هذه الصورة الدائرية المخصصة يمكنك جعل صورتك في شكل دائري مع دائرة نصف قطرها. رفاق دائرية الظل ImageView لا حاجة جيثب هذه الفئة بما فيه الكفاية.

إضافة CircularImageView إلى التخطيط الخاص بك

// Bitmap myimage = BitmapFactory.decodeResource (getResources ()، R.drawable.pic)؛ CircularImageView c = جديد CircularImageView (هذا ، عرض الشاشة ، ارتفاع الشاشة ، صورة نقطية myimage) ؛ yourLayout.addView (ج)؛ **

public class CircularImageView extends Android.support.v7.widget.AppCompatImageView  
{
    private final Context context;
    private final int width, height;
    private final Paint paint;
    private final Paint paintBorder,imagePaint;
    private final Bitmap bitmap2;
    private final Paint paint3;
    private Bitmap bitmap;
    private BitmapShader shader;
    private float radius = 4.0f;
    float x = 0.0f;
    float y = 8.0f;
    private float stroke;
    private float strokeWidth = 0.0f;
    private Bitmap bitmap3;
    private int corner_radius=50;


    public CircularImageView(Context context, int width, int height, Bitmap bitmap)     {
        super(context);
        this.context = context;
        this.width = width;
        this.height = height;

   //here "bitmap" is the square shape(width* width) scaled bitmap ..

        this.bitmap = bitmap;


        Paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        Paint.setAntiAlias(true);
        Paint.setFilterBitmap(true);
        Paint.setDither(true);


        Paint3=new Paint();
        Paint3.setStyle(Paint.Style.STROKE);
        Paint3.setColor(Color.WHITE);
        Paint3.setAntiAlias(true);

        paintBorder = new Paint();
        imagePaint= new Paint();

        paintBorder.setColor(Color.WHITE);
        paintBorder.setAntiAlias(true);
        this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);


        this.bitmap2 = Bitmap.createScaledBitmap(bitmap, (bitmap.getWidth() - 40), (bitmap.getHeight() - 40), true);


        imagePaint.setAntiAlias(true);




        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) 
    {
        super.onDraw(canvas);
        Shader b;
         if (bitmap3 != null)
            b = new BitmapShader(bitmap3, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
         else
            b = new BitmapShader(bitmap2, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        imagePaint.setShader(b);
        canvas.drawBitmap(maskedBitmap(), 20, 20, null);
    }

    private Bitmap maskedBitmap()
    {
        Bitmap l1 = Bitmap.createBitmap(width,width, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(l1);
        paintBorder.setShadowLayer(radius, x, y, Color.parseColor("#454645"));
        Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        final RectF rect = new RectF();
        rect.set(20, 20, bitmap2.getWidth(), bitmap2.getHeight());

        canvas.drawRoundRect(rect, corner_radius, corner_radius, paintBorder);

        canvas.drawRoundRect(rect, corner_radius, corner_radius, imagePaint);

        if (strokeWidth!=0.0f)
        {
            Paint3.setStrokeWidth(strokeWidth);
            canvas.drawRoundRect(rect, corner_radius, corner_radius, Paint3);
        }

         Paint.setXfermode(null);
        return l1;
    }




     // use seekbar here, here you have to pass  "0 -- 250"  here corner radius will change 

    public void setCornerRadius(int corner_radius)
    {
        this.corner_radius = corner_radius;
        invalidate();
    }



    -------->use seekbar here, here you have to pass  "0 -- 10.0f"  here shadow radius will change 

    public void setShadow(float radius)
    {
        this.radius = radius;
        invalidate();
    }

   // use seekbar here, here you have to pass  "0 -- 10.0f"  here stroke size  will change 

    public void setStroke(float stroke)
    {
        this.strokeWidth = stroke;
        invalidate();
    }

    private Bitmap updateSat(Bitmap src, float settingSat)
    {

        int w = src.getWidth();
        int h = src.getHeight();

        Bitmap bitmapResult =
                Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvasResult = new Canvas(bitmapResult);
        Paint paint = new Paint();
        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.setSaturation(settingSat);
        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
        Paint.setColorFilter(filter);
        canvasResult.drawBitmap(src, 0, 0, Paint);

        return bitmapResult;
    }




  // use seekbar here, here you have to pass  "0 -- 2.0f"  here saturation  will change 

    public void setSaturation(float sat)
    {
        System.out.println("qqqqqqqqqq            "+sat);
        bitmap3=updateSat(bitmap2, sat);

        invalidate();
    } 


}






        // Seekbar to change radius

                  radius_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                        @Override
                        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
                        {
                            text_radius.setText(""+progress);
                            circularImageView.setCornerRadius(progress);
                        }

                        @Override
                        public void onStartTrackingTouch(SeekBar seekBar) {

                        }

                        @Override
                        public void onStopTrackingTouch(SeekBar seekBar) {

                        }
                    });


     // Seekbar to change shadow

                    shadow_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                        @Override
                        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
                        {
                            float f= 4+progress/10.0f;
                            text_shadow.setText(""+progress);
                            circularImageView.setShadow(f);
                        }

                        @Override
                        public void onStartTrackingTouch(SeekBar seekBar) {

                        }

                        @Override
                        public void onStopTrackingTouch(SeekBar seekBar) {

                        }
                    });


           // Seekbar to change saturation

                    saturation_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                        @Override
                        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
                        {
                            int progressSat = saturation_seekbar.getProgress();
                            float sat = (float) ((progressSat*4 / 100.0f)-1.0f);
                            circularImageView.setSaturation(sat);

                            text_saturation.setText(""+progressSat);
                        }

                        @Override
                        public void onStartTrackingTouch(SeekBar seekBar) {

                        }

                        @Override
                        public void onStopTrackingTouch(SeekBar seekBar) {

                        }
                    });


    // Seekbar to change stroke

                    stroke_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                        @Override
                        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
                        {
                            if (progress==0)
                            {
                                float f=(progress*10.0f/100.0f);
                                circularImageView.setStroke(f);
                            }
                            else
                            {
                                float f=(progress*10.0f/100.0f);
                                circularImageView.setStroke(f);
                            }

                            text_stroke.setText(""+progress);
                        }

                        @Override
                        public void onStartTrackingTouch(SeekBar seekBar) {

                        }

                        @Override
                        public void onStopTrackingTouch(SeekBar seekBar) {

                        }
                    });




             //radius seekbar in xml file

             <SeekBar
                Android:layout_width="match_parent"
                Android:layout_gravity="center" 
                Android:progress="50"
                Android:max="250"
                Android:id="@+id/radius_seekbar"
                Android:layout_height="wrap_content" />





          //saturation seekbar in xml file

             <SeekBar
                Android:layout_width="match_parent"
                Android:layout_gravity="center" 
                Android:progress="50"
                Android:max="100"
                Android:id="@+id/saturation_seekbar"
                Android:layout_height="wrap_content" />





    //shadow seekbar in xml file

             <SeekBar
                Android:layout_width="match_parent"
                Android:layout_gravity="center" 
                Android:progress="0"
                Android:max="100"
                Android:id="@+id/shadow_seekbar"
                Android:layout_height="wrap_content" />




         //stroke seekbar in xml file

             <SeekBar
                Android:layout_width="match_parent"
                Android:layout_gravity="center" 
                Android:progress="0"
                Android:max="100"
                Android:id="@+id/stroke _seekbar"
                Android:layout_height="wrap_content" />
0
dileep krishnan