缩放图像保持其纵横比在后台可绘制
如何使背景图像适合视图,但使用<bitmap />
作为背景可绘制xml时保持其纵横比? 没有<bitmap>
的android:gravity
值给出了所需的效果。
只能在xml文件中操作背景属性是不可能的。 有两个选项:
-
使用
Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
以编程方式剪切/缩放位Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
并将其设置为某个View
的背景。 -
您使用
ImageView
而不是将背景放置为第一个布局的元素,并android:scaleType
指定android:scaleType
属性:<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/backgrnd" android:scaleType="centerCrop" /> ... rest layout components here ... </RelativeLayout>
有一个简单的方法可以从drawable中做到这一点:
your_drawable.xml
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@color/bg_color"/> <item> <bitmap android:gravity="center|bottom|clip_vertical" android:src="@drawable/your_image" /> </item> </layer-list>
唯一的缺点是,如果没有足够的空间,你的图像将不会被完全显示出来,但是会被剪切掉,我找不到一个直接从drawable中做到这一点的方法。 但是从testing中我发现它工作得很好,而且不会剪切太多的图像。 你可以玩更多的重力选项。
另一种方法是创build一个布局,在那里你将使用ImageView
并将scaleType
设置为fitCenter
。
希望这些信息可以帮助你实现你想要的。
另一种方法是创build普通图像的补丁9图像 ,并按照您希望的方式进行缩放。
你可以通过在angular落放9个补丁点来显示内容的中心位置,这样可以明显地保持你的比例(假设图像的最外边是可重复/透明的)。
希望你明白了。
使用a.ch描述的方法对我来说工作得非常好,除了我使用了这个比例更好的types,
android:scaleType="centerCrop"
以下是可用缩放types的完整列表: http : //developer.android.com/reference/android/widget/ImageView.ScaleType.html
尝试使用InsetDrawable(为我工作得很好)。
只要给你这个可绘制的,并从四边中的任何一边你想要的插入(或填充)。
InsetDrawable insetDrawable = new InsetDrawable(drawable, insetLeft, insetTop, insetRight, insetBottom);
它是专门用于设置背景绘制,尺寸较小或比视图。
看到这里: https : //developer.android.com/reference/android/graphics/drawable/InsetDrawable.html
老问题,但没有其他答案为我工作。 但是,这个XML代码做到了:
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:scaleType="centerCrop" android:src="@drawable/background_image"/> </RelativeLayout>
如果您的位图宽度比较大,请使用android:gravity="fill_vertical"
。 否则,使用android:gravity="fill_horitzonal"
。 这与在ImageView
上使用android:scaleType="centerCrop"
具有类似的效果。
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="fill_vertical" android:src="@drawable/image" />
如果您支持多个方向,则可以在drawable-port
文件夹中创build一个位图XML文件,而在drawable-land
文件夹中创build另一个位图XML文件。
我想在我的自定义Drawable类中做类似的事情。 以下是重要的部分:
public class CustomBackgroundDrawable extends Drawable { private Rect mTempRect = new Rect(); private Paint mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); ... public void draw(@NonNull Canvas canvas) { Rect bounds = getBounds(); if (mBitmap != null ) { if (mScaleType == ScaleType.SCALE_FILL) { //bitmap scales to fill the whole bounds area (bitmap can be cropped) if (bounds.height() > 0 && bounds.height() > 0) { float scale = Math.min(mBitmap.getWidth()/(float)bounds.width(), mBitmap.getHeight()/(float)bounds.height()); float bitmapVisibleWidth = scale * bounds.width(); float bitmapVisibleHeight = scale * bounds.height(); mTempRect.set((int)(mBitmap.getWidth()-bitmapVisibleWidth)/2, 0, (int)(bitmapVisibleWidth+mBitmap.getWidth())/2, (int)bitmapVisibleHeight); canvas.drawBitmap(mBitmap, mTempRect, bounds, mBitmapPaint); } } else if (mScaleType == ScaleType.SCALE_FIT) { //bitmap scales to fit in bounds area if (bounds.height() > 0 && bounds.height() > 0) { float scale = Math.min((float)bounds.width()/mBitmap.getWidth(), (float)bounds.height()/mBitmap.getHeight()); float bitmapScaledWidth = scale * mBitmap.getWidth(); float bitmapScaledHeight = scale * mBitmap.getHeight(); int centerPadding = (int)(bounds.width()-bitmapScaledWidth)/2; mTempRect.set(bounds.left + centerPadding, bounds.top, bounds.right - centerPadding, bounds.top+(int)bitmapScaledHeight); canvas.drawBitmap(mBitmap, null, mTempRect, mBitmapPaint); } } } }
使用这种方法,您可以灵活地应用所需的任何比例逻辑