从相机调整图像大小以适合 Imageview

Posted

技术标签:

【中文标题】从相机调整图像大小以适合 Imageview【英文标题】:Resize image from camera to fit Imageview 【发布时间】:2015-10-07 09:27:56 【问题描述】:

我有一个圆形图像视图。我正在将图像从相机和画廊设置为 ImageView。问题是当我从相机设置图像时,图像在圆形图像视图中看起来过于拉伸。

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

这是我的工作:

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;
        

mylayout.xml

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

主活动

int imgheight = Resources.DisplayMetrics.HeightPixels;

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

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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

毕加索也可作为组件使用components.xamarin.com/view/square.picasso @Niv 这也没有帮助.. 图像仍然伸展 你用过parameter.resize(x,y)吗? Picasso.With(context) .Load(url) .Resize(200, 200) .CenterCrop() .Into(imageView);

以上是关于从相机调整图像大小以适合 Imageview的主要内容,如果未能解决你的问题,请参考以下文章

调整UIImageView的大小以包装“适合方面”的图像

调整图像大小以适合图像视图

自动调整 UIImageView 的大小以适合底层图像

水平图像滚动,图像大小调整以适合高度显示空白空间

调整背景图像大小以适合 div [重复]

如何水平调整图像大小(通过 CSS)以适合框?