android - 调整来自相机的图像大小以适合 Imageview

标签 android xamarin camera image-gallery

我有一个 Cirle imageview。我正在将图像设置为来自相机和画廊的 ImageView。问题是,当我设置来自相机的图像时,图像在圆形 ImageView 中看起来过于拉伸(stretch)。

我正在调整图像大小以避免任何内存泄漏。

这是我的做法:

CircleImageView.cs

public class CircleImageView : ImageView
    {
        private int borderWidth;
        private int canvasSize;
        private Bitmap image;
        private Paint paint;
        private Paint paintBorder;


        public CircleImageView(Context context)
            : this(context, null)
        {
        }

        public CircleImageView(Context context, IAttributeSet attrs)
            : this(context, attrs, Resource.Attribute.circularImageViewStyle)
        {
        }

        public CircleImageView(Context context, IAttributeSet attrs, int defStyle)
            : base(context, attrs, defStyle)
        {

            // init paint
            paint = new Paint();
            paint.AntiAlias = true;

            paintBorder = new Paint();
            paintBorder.AntiAlias = true;

            // load the styled attributes and set their properties
            TypedArray attributes = context.ObtainStyledAttributes(attrs, Resource.Styleable.CircularImageView, defStyle, 0);

            if (attributes.GetBoolean(Resource.Styleable.CircularImageView_border, true))
            {
                int defaultBorderSize = (int)(4 * context.Resources.DisplayMetrics.Density+ 0.5f);
                BorderWidth = attributes.GetDimensionPixelOffset(Resource.Styleable.CircularImageView_border_width, defaultBorderSize);
                BorderColor = attributes.GetColor(Resource.Styleable.CircularImageView_border_color, Color.White);
            }

            if (attributes.GetBoolean(Resource.Styleable.CircularImageView_shadow, false))
            {
                addShadow();
            }
        }
        public void addShadow()
        {
            SetLayerType(LayerType.Software, paintBorder);
            paintBorder.SetShadowLayer(4.0f, 2.0f, 2.0f, Color.ParseColor("#82C341"));
        }
        public virtual int BorderWidth
        {
            set
            {
                this.borderWidth = 10;
                this.RequestLayout();
                this.Invalidate();
            }
        }

        public virtual int BorderColor
        {
            set
            {
                if (paintBorder != null)
                {
                    paintBorder.Color = Color.Gray;
                }
                this.Invalidate();
            }
        }
        protected override void OnDraw(Canvas canvas)
        {
            // load the bitmap
            image = drawableToBitmap(Drawable);

            // init shader
            if (image != null)
            {

                canvasSize = canvas.Width;
                if (canvas.Height < canvasSize)
                {
                    canvasSize = canvas.Height;
                }

                BitmapShader shader = new BitmapShader(Bitmap.CreateScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.Clamp, Shader.TileMode.Clamp);
                paint.SetShader(shader);

                // 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
                int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
                canvas.DrawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
                canvas.DrawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
            }
        }

        protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            int width = measureWidth(widthMeasureSpec);
            int height = measureHeight(heightMeasureSpec);
            SetMeasuredDimension(width, height);
        }

        private int measureWidth(int measureSpec)
        {
            int result = 0;
            var specMode = MeasureSpec.GetMode(measureSpec);
            var specSize = MeasureSpec.GetSize(measureSpec);

            if (specMode == MeasureSpecMode.Exactly)
            {
                // The parent has determined an exact size for the child.
                result = specSize;
            }
            else if (specMode == MeasureSpecMode.AtMost)
            {
                // The child can be as large as it wants up to the specified size.
                result = specSize;
            }
            else
            {
                // The parent has not imposed any constraint on the child.
                result = canvasSize;
            }

            return result;
        }

        private int measureHeight(int measureSpecHeight)
        {
            int result = 0;
            var specMode = MeasureSpec.GetMode(measureSpecHeight);
            int specSize = MeasureSpec.GetSize(measureSpecHeight);

            if (specMode == MeasureSpecMode.Exactly)
            {
                // We were told how big to be
                result = specSize;
            }
            else if (specMode == MeasureSpecMode.AtMost)
            {
                // The child can be as large as it wants up to the specified size.
                result = specSize;
            }
            else
            {
                // Measure the text (beware: ascent is a negative number)
                result = canvasSize;
            }

            return (result + 2);
        }

        public virtual Bitmap drawableToBitmap(Drawable drawable)
        {
            if (drawable == null)
            {
                return null;
            }
            else if (drawable is BitmapDrawable)
            {
                return ((BitmapDrawable)drawable).Bitmap;
            }

            Bitmap bitmap = Bitmap.CreateBitmap(drawable.IntrinsicWidth, drawable.IntrinsicHeight, Bitmap.Config.Argb8888);
            Canvas canvas = new Canvas(bitmap);
            drawable.SetBounds(0, 0, canvas.Width, canvas.Height);
            drawable.Draw(canvas);

            return bitmap;
        }
    }

BitmapHelper.cs

public static Bitmap LoadAndResizeBitmap(this string fileName, int width, int height)
        {

            // First we get the the dimensions of the file on disk
            BitmapFactory.Options options = new BitmapFactory.Options { InJustDecodeBounds = true };
            BitmapFactory.DecodeFile(fileName, options);

            // Next we calculate the ratio that we need to resize the image by
            // in order to fit the requested dimensions.
            int outHeight = options.OutHeight;
            int outWidth = options.OutWidth;
            int inSampleSize = 1;

            if (outHeight > height || outWidth > width)
            {
                inSampleSize = outWidth > outHeight
                                   ? outHeight / height
                                   : outWidth / width;
            }

            // Now we will load the image and have BitmapFactory resize it for us.
            options.InSampleSize = inSampleSize;
            options.InJustDecodeBounds = false;
            Bitmap resizedBitmap = BitmapFactory.DecodeFile(fileName, options);

            return resizedBitmap;
        }

我的布局.xml

 <Utilities.CircleImageView
                    android:layout_width="180dp"
                    android:layout_height="180dp"
                    android:id="@+id/imgProfileCircleImage"
                    android:src="@drawable/rapidicon"
                    custom:border="true"
                    custom:border_color="#d5d5d5"
                    custom:border_width="4dp"
                    custom:shadow="true"
                    android:layout_gravity="center"
                    android:minHeight="80dp"
                    android:minWidth="80dp" />

主要 Activity

int imgheight = Resources.DisplayMetrics.HeightPixels;

            int circleImgWidth = imgProfileCircleImage.Height;
            AppHelper._bitmap = AppHelper._file.Path.LoadAndResizeBitmap(circleImgWidth, imgheight);

如何设置图像以使其看起来完全适合 imageview?

最佳答案

尝试使用 Picasso 或 Glide 轻松解决此问题

http://square.github.io/picasso/

关于android - 调整来自相机的图像大小以适合 Imageview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32988637/

相关文章:

android - Espresso 单击具有特定 id 的每个元素

android - 从右到左 Android 应用中的选项卡滑动方向

c# - Xamarin Android - 隐藏 TextView

iphone - 什么是 CG 插值质量?

c# - Xamarin 表单和 Android 蓝牙

android - 使用 WakeLock 时屏幕打开然后关闭的速度太快(没有保持打开几秒钟)

android - 在 ListView 中动态更改 TextView 字体颜色

c# - 更新到最新的 Xcode 和 VS 后,Xamarin ios 编译到 Iphone 失败

java - 使用前置摄像头但仍然打开闪光灯

android - Camera2Basic 应用程序前置摄像头将照片颠倒