从相机调整图像大小以适合 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的主要内容,如果未能解决你的问题,请参考以下文章