使位图在 x 方向可绘制平铺,但在 y 方向拉伸

发布于 2024-12-05 04:32:29 字数 476 浏览 0 评论 0原文

我有一个图像用作相对布局的背景。图像需要水平平铺才能形成图案。

我可以使用以下代码使图像水平平铺:

BitmapDrawable b3 = (BitmapDrawable)getResources().getDrawable(R.drawable.background);

b3.setTileModeX(Shader.TileMode.REPEAT);

v.findViewById(R.id.layout).setBackgroundDrawable(b3);

问题是图像也垂直平铺。它似乎在垂直方向上以“夹紧”模式平铺,但在水平方向上以“重复”模式平铺。这是一个屏幕截图:

TileMode

如您所见,图像比它所占用的空间小一点点,并且底部边缘被“夹紧”。

如何将图像设置为垂直拉伸但水平平铺?

I have an image which I'm using as a background for a RelativeLayout. The image needs to be tiled horizontally to make a pattern.

I'm able to get the image to tile horizontally by using this code:

BitmapDrawable b3 = (BitmapDrawable)getResources().getDrawable(R.drawable.background);

b3.setTileModeX(Shader.TileMode.REPEAT);

v.findViewById(R.id.layout).setBackgroundDrawable(b3);

The problem is that the image also tiles vertically. It seems to tile in the "clamp" mode in the vertical, but "repeat" mode in the horizontal. Here is a screenshot:

TileMode

As you can see, the image is just a little bit smaller than the space it occupies, and the bottom edge is "clamped".

How can I set the image to stretch vertically but tile horizontally?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦途 2024-12-12 04:32:29

此方法调用创建新位图,但看起来它正在实现您的目标

        View view = findViewById(R.id.layout);
        BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(R.drawable.tile);
        int width = view.getWidth();
        int intrinsicHeight = bd.getIntrinsicHeight();
        Rect bounds = new Rect(0,0,width,intrinsicHeight);
        bd.setTileModeX(TileMode.REPEAT);
        bd.setBounds(bounds);
        Bitmap bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), bd.getBitmap().getConfig());
        Canvas canvas = new Canvas(bitmap);
        bd.draw(canvas);
        BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
        view.setBackground(bitmapDrawable);

。请注意,它仅在视图已布局的情况下才有效,因此方法 lile onWindowFocusChanged 是放置此代码的好地方。

This method invokes creation of new bitmap but it looks like it's acrhiving your goal

        View view = findViewById(R.id.layout);
        BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(R.drawable.tile);
        int width = view.getWidth();
        int intrinsicHeight = bd.getIntrinsicHeight();
        Rect bounds = new Rect(0,0,width,intrinsicHeight);
        bd.setTileModeX(TileMode.REPEAT);
        bd.setBounds(bounds);
        Bitmap bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), bd.getBitmap().getConfig());
        Canvas canvas = new Canvas(bitmap);
        bd.draw(canvas);
        BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
        view.setBackground(bitmapDrawable);

Please note that it only works if view was already layouted, so a method lile onWindowFocusChanged is a good place for this code.

只怪假的太真实 2024-12-12 04:32:29

我觉得它很简单:(此代码将在 Y 中平铺并在 x 中重复)

在您的 onWindowFoucsChanged 中您调用:

 public void onWindowFocusChanged(boolean hasFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasFocus);
        Drawable d = getRepeatingBG(this, R.drawable.image_that_you_want_to_repeat);
        body_view.setBackgroundDrawable(d);

    }

private Drawable getRepeatingBG(Activity activity, int center)
    {   

        DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled=true;

        Bitmap center_bmp = BitmapFactory.decodeResource(activity.getResources(), center, options);
        center_bmp.setDensity(Bitmap.DENSITY_NONE);
        center_bmp=Bitmap.createScaledBitmap(center_bmp, dm.widthPixels , center_bmp.getHeight(), true);

        BitmapDrawable center_drawable = new BitmapDrawable(activity.getResources(),center_bmp);
//change here setTileModeY to setTileModeX if you want to repear in X
        center_drawable.setTileModeY(Shader.TileMode.REPEAT);

        return center_drawable;
    }

I feel it is straight forward:(This code will tile in Y and repeat in x)

In your onWindowFoucsChanged you call:

 public void onWindowFocusChanged(boolean hasFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasFocus);
        Drawable d = getRepeatingBG(this, R.drawable.image_that_you_want_to_repeat);
        body_view.setBackgroundDrawable(d);

    }

private Drawable getRepeatingBG(Activity activity, int center)
    {   

        DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled=true;

        Bitmap center_bmp = BitmapFactory.decodeResource(activity.getResources(), center, options);
        center_bmp.setDensity(Bitmap.DENSITY_NONE);
        center_bmp=Bitmap.createScaledBitmap(center_bmp, dm.widthPixels , center_bmp.getHeight(), true);

        BitmapDrawable center_drawable = new BitmapDrawable(activity.getResources(),center_bmp);
//change here setTileModeY to setTileModeX if you want to repear in X
        center_drawable.setTileModeY(Shader.TileMode.REPEAT);

        return center_drawable;
    }
明媚殇 2024-12-12 04:32:29

对你来说太晚了,但对其他人可能有用。

您可以创建自定义视图来执行此操作。只需将源位图缩放到与视图一样高,然后在画布上重复绘制它:

public class RepeatingXImageView extends View {

Bitmap bitmap;
Paint paint;

public RepeatingXImageView(Context context) {
    super(context);
}

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

public RepeatingXImageView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    if(changed) {
        paint = new Paint();
        bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.seekbar_overlay);
        bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bottom - top, false);
    }
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if(bitmap == null) return;
    int left = 0;
    while(left < getWidth()) {
        canvas.drawBitmap(bitmap, left, 0, paint);
        left += bitmap.getWidth();
    }
}
}

Far too late for you, but may be useful for others.

You can create a custom View in order to do this. Simply scale your source bitmap to be as high as your view and then draw it repeatedly on the canvas:

public class RepeatingXImageView extends View {

Bitmap bitmap;
Paint paint;

public RepeatingXImageView(Context context) {
    super(context);
}

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

public RepeatingXImageView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    if(changed) {
        paint = new Paint();
        bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.seekbar_overlay);
        bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bottom - top, false);
    }
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if(bitmap == null) return;
    int left = 0;
    while(left < getWidth()) {
        canvas.drawBitmap(bitmap, left, 0, paint);
        left += bitmap.getWidth();
    }
}
}
拔了角的鹿 2024-12-12 04:32:29

我自己也有同样的问题。尝试使用 9patch 图像,但似乎您不能将 9patch 图像与平铺一起使用,无论您在平铺属性中定义什么,9patch 都会拉伸图像。
最后我要做的就是要求图像的创建者将其垂直拉伸或自己做。如果有人找到一个更好的解决方案,我希望有一个更好的解决方案。

Having the same problem myself. Tried using 9patch image but it seems you cannot use 9patch images along with tiling, the 9patch stretches the image no matter what you define in the tiling property.
At the end what i will do is ask the creator of the image to stretch it vertically or do it myself. I would love a better solution if anyone finds one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文