Android 平铺位图

发布于 2024-08-02 10:30:16 字数 266 浏览 3 评论 0原文

我正在尝试在 Android 中加载一个我想要平铺的位图。我目前在视图中使用以下内容来显示位图:

canvas.drawBitmap(bitmap, srcRect, destRect, null)

我本质上想在我的应用程序中使用此位图作为背景图像,并且希望在 X 和 Y 方向上重复该位图。

我已经看到了 BitmapShader 类的 TileMode.REPEAT 常量,但我不确定这是否用于重复实际位图或用于对位图应用过滤器。

I'm trying to load a bitmap in Android which I want to tile. I'm currently using the following in my view to display a bitmap:

canvas.drawBitmap(bitmap, srcRect, destRect, null)

I essentially want to use this bitmap as a background image in my app and would like to repeat the bitmap in both the X and Y directions.

I've seen the TileMode.REPEAT constant for the BitmapShader class but i am not sure if this is to be used for repeating the actual bitmap or is used for applying a filter to the bitmap.

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

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

发布评论

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

评论(8

一梦等七年七年为一梦 2024-08-09 10:30:16

您可以在 xml 而不是 java 代码中执行此操作。我自己没有尝试过,但我确实找到了这个例子。

<xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/MainLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@drawable/backrepeat"
>

然后在一个名为 backrepeat.xml

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/back" 
    android:tileMode="repeat" />

reference

You would do this in the xml instead of the java code. I haven't attempted this myself but I did find this example.

<xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/MainLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@drawable/backrepeat"
>

then in an xml called backrepeat.xml

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/back" 
    android:tileMode="repeat" />

reference

不再见 2024-08-09 10:30:16

找出代码版本:

  BitmapDrawable TileMe = new BitmapDrawable(MyBitmap);
  TileMe.setTileModeX(Shader.TileMode.REPEAT);
  TileMe.setTileModeY(Shader.TileMode.REPEAT);

  ImageView Item = new ImageView(this);
  Item.setBackgroundDrawable(TileMe);

然后,如果您有一个可绘制的平铺,则可以使用它来制作 BitmapDrawable:

  BitmapDrawable TileMe = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.tile));

Figured out the code version:

  BitmapDrawable TileMe = new BitmapDrawable(MyBitmap);
  TileMe.setTileModeX(Shader.TileMode.REPEAT);
  TileMe.setTileModeY(Shader.TileMode.REPEAT);

  ImageView Item = new ImageView(this);
  Item.setBackgroundDrawable(TileMe);

Then if you have a drawable to tile, this can be used instead to make the BitmapDrawable:

  BitmapDrawable TileMe = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.tile));
花海 2024-08-09 10:30:16

上面的 backrepeat.xml 有问题

<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/tile"
    android:tileMode="repeat"
    android:dither="true" />

The backrepeat.xml above is buggy

<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/tile"
    android:tileMode="repeat"
    android:dither="true" />
忆沫 2024-08-09 10:30:16

似乎有些人有兴趣在 View 的 onDraw 方法中执行此操作。以下代码对我有用:

bgTile = BitmapFactory.decodeResource(context.getResources(), R.drawable.bg_tile);

float left = 0, top = 0;
float bgTileWidth = bgTile.getWidth();
float bgTileHeight = bgTile.getHeight();

while (left < screenWidth) {
    while (top < screenHeight) {
        canvas.drawBitmap(bgTile, left, top, null);
        top += bgTileHeight;
    }
    left += bgTileWidth;
    top = 0;
}

It seems that some people are interested in doing this in a View, at the onDraw method. The following code has worked for me:

bgTile = BitmapFactory.decodeResource(context.getResources(), R.drawable.bg_tile);

float left = 0, top = 0;
float bgTileWidth = bgTile.getWidth();
float bgTileHeight = bgTile.getHeight();

while (left < screenWidth) {
    while (top < screenHeight) {
        canvas.drawBitmap(bgTile, left, top, null);
        top += bgTileHeight;
    }
    left += bgTileWidth;
    top = 0;
}
北陌 2024-08-09 10:30:16
<xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/MainLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="@drawable/back"
    android:tileMode="repeat"
>

这对我来说效果很好。我不必单独创建位图。我在布局中使用了tileMode 属性。

<xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/MainLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="@drawable/back"
    android:tileMode="repeat"
>

This worked fine for me. I did not have to create the bitmap seperately. I used the tileMode attribute in the layout.

汐鸠 2024-08-09 10:30:16

只需将这行代码放在 onCreate() 中即可:-

 final Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.actionbar_bg);
 final BitmapDrawable bitmapDrawable = new BitmapDrawable(bmp);
 bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
 final ActionBar bar = getSupportActionBar();
 bar.setBackgroundDrawable(bitmapDrawable);

Just put this line of codes in the onCreate():-

 final Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.actionbar_bg);
 final BitmapDrawable bitmapDrawable = new BitmapDrawable(bmp);
 bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
 final ActionBar bar = getSupportActionBar();
 bar.setBackgroundDrawable(bitmapDrawable);
梅窗月明清似水 2024-08-09 10:30:16

如果您只想垂直重复背景,您可以将布局的宽度设置为“wrap_content”,而如果您想将背景设置为水平重复,则将高度设置为“wrap_content”。如果高度和宽度都设置为“fill_parent”,那么它将沿 X 和 Y 方向平铺。

例如,以下代码将垂直重复您的背景:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:background="@drawable/news_detail_activity_bg">
</LinearLayout>

If you want to repeat the background only vertically you can set the width of your layout to "wrap_content", whereas if you want to set the background to repeat horizontally set the height to "wrap_content". If both height and width are set to "fill_parent" then it will tile in the X and Y directions.

For example, the following code will repeat your background vertically:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:background="@drawable/news_detail_activity_bg">
</LinearLayout>
儭儭莪哋寶赑 2024-08-09 10:30:16
/* Tiled Layer Bitmap*/


public class TiledLayer {
private int cellWidth;
private int cellHeight;
private int yPosition = 0, xPosition = 0;
private int[][] grid;
private Image image;
private int[] tileXPositions;
private int[] tileYPositions;
private ArrayList animatedTiles;
private int numberOfTiles;
private int numberOfColumns;
private int numberOfRows;
private int gridColumns;
private int gridRows, width, height;

public TiledLayer(Image image, int columns, int rows, int tileWidth,
        int tileHeight, int width, int height) {
    this.grid = new int[columns][rows];
    this.gridColumns = columns;
    this.gridRows = rows;
    this.width = columns * tileWidth;
    this.height = rows * tileHeight;
    this.animatedTiles = new ArrayList();
    setStaticTileSet(image, tileWidth, tileHeight);
}

public void setStaticTileSet(Image image, int tileWidth, int tileHeight) {
    this.image = image;
    this.cellWidth = tileWidth;
    this.cellHeight = tileHeight;
    int columns = 64;//image.getWidth() / tileWidth;
    int rows =40;// image.getHeight() / tileHeight;
    this.tileXPositions = new int[columns];
    int pos = 0;
    for (int i = 0; i < columns; i++) {
        this.tileXPositions[i] = pos;
        pos += tileWidth;
    }
    this.tileYPositions = new int[rows];
    pos = 0;
    for (int i = 0; i < rows; i++) {
        this.tileYPositions[i] = pos;
        pos += tileHeight;
    }

    if (columns * rows < this.numberOfTiles) {
        // clear the grid, when there are not as many tiles as in the
        // previous set:
        for (int i = 0; i < this.grid.length; i++) {
            for (int j = 0; j < this.grid[i].length; j++) {
                this.grid[i][j] = 0;
            }
        }
    }
    this.numberOfTiles = columns * rows;
    this.numberOfColumns = columns;
    this.numberOfRows = rows;
}

public int createAnimatedTile(int staticTileIndex) {
    if (staticTileIndex >= this.numberOfTiles) {

        throw new IllegalArgumentException("invalid static tile index: "
                + staticTileIndex + " (there are only ["
                + this.numberOfTiles + "] tiles available.");

    }
    this.animatedTiles.add(new Integer(staticTileIndex));
    return -1 * (this.animatedTiles.size() - 1);
}

public void setAnimatedTile(int animatedTileIndex, int staticTileIndex) {
    if (staticTileIndex >= this.numberOfTiles) {

    }
    int animatedIndex = (-1 * animatedTileIndex) - 1;
    this.animatedTiles.set(animatedIndex, new Integer(staticTileIndex));
 }

 public int getAnimatedTile(int animatedTileIndex) {
    int animatedIndex = (-1 * animatedTileIndex) - 1;
    Integer animatedTile = (Integer) this.animatedTiles.get(animatedIndex);
    return animatedTile.intValue();
 }
 public void setCell(int col, int row, int tileIndex) {
    if (tileIndex >= this.numberOfTiles) {

        throw new IllegalArgumentException("invalid static tile index: "
                + tileIndex + " (there are only [" + this.numberOfTiles
                + "] tiles available.");

    }
    this.grid[col][row] = tileIndex;
}

 public int getCell(int col, int row) {
    return this.grid[col][row];
 }

 public void fillCells(int col, int row, int numCols, int numRows,
        int tileIndex) {
    if (tileIndex >= this.numberOfTiles) {

        throw new IllegalArgumentException("invalid static tile index: "
                + tileIndex + " (there are only [" + this.numberOfTiles
                + "] tiles available.");

    }
    int endCols = col + numCols;
    int endRows = row + numRows;
    for (int i = col; i < endCols; i++) {
        for (int j = row; j < endRows; j++) {
            this.grid[i][j] = tileIndex;
        }
    }
 }

    public final int getCellWidth() {
    return this.cellWidth;
 }

    public final int getCellHeight() {
    return this.cellHeight;
 }

 public final int getColumns() {
    return this.gridColumns;
 }

public final int getRows() {
    return this.gridRows;
}

public final void paint(Graphics g) {
    int clipX = 0;// g.getClipX();
    int clipY = 0;// g.getClipY();
    int clipWidth = width;// g.getClipWidth();
    int clipHeight = height;// g.getClipHeight();

    // jmt restore clip to previous state

    int x = this.xPosition;
    int y = this.yPosition;
    int[][] gridTable = this.grid;
    for (int i = 0; i < this.gridColumns; i++) {
        int[] gridRow = gridTable[i];
        for (int j = 0; j < gridRow.length; j++) {
            int cellIndex = gridRow[j];
            if (cellIndex != 0) {
                // okay this cell needs to be rendered:
                int tileIndex;
                if (cellIndex < 0) {
                    Integer tile = (Integer) this.animatedTiles
                            .get((-1 * cellIndex) - 1);
                    tileIndex = tile.intValue() - 1;
                } else {
                    tileIndex = cellIndex - 1;
                }
                // now draw the tile:
                g.save(Canvas.CLIP_SAVE_FLAG);
                // jmt: clear the screen
                Rect r = new Rect(0, 0, cellWidth, cellHeight);
                g.clipRect(r);
                g.setClip(x, y, this.cellWidth, this.cellHeight);
                int column = tileIndex % this.numberOfColumns;
                int row = tileIndex / this.numberOfColumns;
                int tileX = x - this.tileXPositions[column];
                int tileY = y - this.tileYPositions[row];

                g.drawImage(this.image, tileX, tileY);
                g.restore();
            }
            y += this.cellHeight;
        } // for each row
        y = this.yPosition;
        x += this.cellWidth;
    } // for each column

        // reset original clip:
        g.setClip(clipX, clipY, clipWidth, clipHeight);
     }
}
/* Tiled Layer Bitmap*/


public class TiledLayer {
private int cellWidth;
private int cellHeight;
private int yPosition = 0, xPosition = 0;
private int[][] grid;
private Image image;
private int[] tileXPositions;
private int[] tileYPositions;
private ArrayList animatedTiles;
private int numberOfTiles;
private int numberOfColumns;
private int numberOfRows;
private int gridColumns;
private int gridRows, width, height;

public TiledLayer(Image image, int columns, int rows, int tileWidth,
        int tileHeight, int width, int height) {
    this.grid = new int[columns][rows];
    this.gridColumns = columns;
    this.gridRows = rows;
    this.width = columns * tileWidth;
    this.height = rows * tileHeight;
    this.animatedTiles = new ArrayList();
    setStaticTileSet(image, tileWidth, tileHeight);
}

public void setStaticTileSet(Image image, int tileWidth, int tileHeight) {
    this.image = image;
    this.cellWidth = tileWidth;
    this.cellHeight = tileHeight;
    int columns = 64;//image.getWidth() / tileWidth;
    int rows =40;// image.getHeight() / tileHeight;
    this.tileXPositions = new int[columns];
    int pos = 0;
    for (int i = 0; i < columns; i++) {
        this.tileXPositions[i] = pos;
        pos += tileWidth;
    }
    this.tileYPositions = new int[rows];
    pos = 0;
    for (int i = 0; i < rows; i++) {
        this.tileYPositions[i] = pos;
        pos += tileHeight;
    }

    if (columns * rows < this.numberOfTiles) {
        // clear the grid, when there are not as many tiles as in the
        // previous set:
        for (int i = 0; i < this.grid.length; i++) {
            for (int j = 0; j < this.grid[i].length; j++) {
                this.grid[i][j] = 0;
            }
        }
    }
    this.numberOfTiles = columns * rows;
    this.numberOfColumns = columns;
    this.numberOfRows = rows;
}

public int createAnimatedTile(int staticTileIndex) {
    if (staticTileIndex >= this.numberOfTiles) {

        throw new IllegalArgumentException("invalid static tile index: "
                + staticTileIndex + " (there are only ["
                + this.numberOfTiles + "] tiles available.");

    }
    this.animatedTiles.add(new Integer(staticTileIndex));
    return -1 * (this.animatedTiles.size() - 1);
}

public void setAnimatedTile(int animatedTileIndex, int staticTileIndex) {
    if (staticTileIndex >= this.numberOfTiles) {

    }
    int animatedIndex = (-1 * animatedTileIndex) - 1;
    this.animatedTiles.set(animatedIndex, new Integer(staticTileIndex));
 }

 public int getAnimatedTile(int animatedTileIndex) {
    int animatedIndex = (-1 * animatedTileIndex) - 1;
    Integer animatedTile = (Integer) this.animatedTiles.get(animatedIndex);
    return animatedTile.intValue();
 }
 public void setCell(int col, int row, int tileIndex) {
    if (tileIndex >= this.numberOfTiles) {

        throw new IllegalArgumentException("invalid static tile index: "
                + tileIndex + " (there are only [" + this.numberOfTiles
                + "] tiles available.");

    }
    this.grid[col][row] = tileIndex;
}

 public int getCell(int col, int row) {
    return this.grid[col][row];
 }

 public void fillCells(int col, int row, int numCols, int numRows,
        int tileIndex) {
    if (tileIndex >= this.numberOfTiles) {

        throw new IllegalArgumentException("invalid static tile index: "
                + tileIndex + " (there are only [" + this.numberOfTiles
                + "] tiles available.");

    }
    int endCols = col + numCols;
    int endRows = row + numRows;
    for (int i = col; i < endCols; i++) {
        for (int j = row; j < endRows; j++) {
            this.grid[i][j] = tileIndex;
        }
    }
 }

    public final int getCellWidth() {
    return this.cellWidth;
 }

    public final int getCellHeight() {
    return this.cellHeight;
 }

 public final int getColumns() {
    return this.gridColumns;
 }

public final int getRows() {
    return this.gridRows;
}

public final void paint(Graphics g) {
    int clipX = 0;// g.getClipX();
    int clipY = 0;// g.getClipY();
    int clipWidth = width;// g.getClipWidth();
    int clipHeight = height;// g.getClipHeight();

    // jmt restore clip to previous state

    int x = this.xPosition;
    int y = this.yPosition;
    int[][] gridTable = this.grid;
    for (int i = 0; i < this.gridColumns; i++) {
        int[] gridRow = gridTable[i];
        for (int j = 0; j < gridRow.length; j++) {
            int cellIndex = gridRow[j];
            if (cellIndex != 0) {
                // okay this cell needs to be rendered:
                int tileIndex;
                if (cellIndex < 0) {
                    Integer tile = (Integer) this.animatedTiles
                            .get((-1 * cellIndex) - 1);
                    tileIndex = tile.intValue() - 1;
                } else {
                    tileIndex = cellIndex - 1;
                }
                // now draw the tile:
                g.save(Canvas.CLIP_SAVE_FLAG);
                // jmt: clear the screen
                Rect r = new Rect(0, 0, cellWidth, cellHeight);
                g.clipRect(r);
                g.setClip(x, y, this.cellWidth, this.cellHeight);
                int column = tileIndex % this.numberOfColumns;
                int row = tileIndex / this.numberOfColumns;
                int tileX = x - this.tileXPositions[column];
                int tileY = y - this.tileYPositions[row];

                g.drawImage(this.image, tileX, tileY);
                g.restore();
            }
            y += this.cellHeight;
        } // for each row
        y = this.yPosition;
        x += this.cellWidth;
    } // for each column

        // reset original clip:
        g.setClip(clipX, clipY, clipWidth, clipHeight);
     }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文