Mapa de bits de mosaico de Android
Estoy tratando de cargar un mapa de bits en Android que quiero azulejo. Actualmente utilizo lo siguiente en mi vista para mostrar un mapa de bits:
canvas.drawBitmap(bitmap, srcRect, destRect, null)
Quiero esencialmente utilizar este mapa de bits como una imagen de fondo en mi aplicación y me gustaría repetir el mapa de bits en las direcciones X e Y.
- Bitmap decodeStream OutOfMemory Excepción
- View.getDrawingCache () sólo funciona una vez
- Android: crear imagen circular con picasso
- Dibujo punteado (...) camino en lugar de una línea (________)
- Botón para Android Sherlock ActionBar Up
He visto la constante de TileMode.REPEAT para la clase de BitmapShader pero soy inseguro si esto está a hacer con repetir el mapa de bits real oa hacer con aplicar un filtro al mapa de bits.
- BitmapFactory.decodeResource devuelve un mapa de bits mutable en Android 2.2 y un mapa de bits inmutable en Android 1.6
- Problema de conversión de URI a Bitmap (2014):
- Android + cargador universal de imágenes: muestra marcador personalizado con imagen en google map
- Aumentar la memoria asignada a la aplicación
- Crear un nuevo mapa de bits y dibujar nuevos píxeles en él
- Android SkImageDecoder :: Factory devuelto null Error
- Combinación de 2 imágenes superpuestas
- ¿Cómo puedo fusionar dos mapas de bits uno sobre otro en el punto seleccionado en la primera imagen en android?
Usted haría esto en el xml en vez del código de java. No he intentado esto yo mismo, pero encontré este ejemplo.
<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" >
Luego en un xml llamado backrepeat.xml
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/back" android:tileMode="repeat" />
referencia
Calculó la versión de código:
BitmapDrawable TileMe = new BitmapDrawable(MyBitmap); TileMe.setTileModeX(Shader.TileMode.REPEAT); TileMe.setTileModeY(Shader.TileMode.REPEAT); ImageView Item = new ImageView(this); Item.setBackgroundDrawable(TileMe);
Entonces si usted tiene un azulejo dibujable, éste se puede utilizar en lugar de otro para hacer el BitmapDrawable:
BitmapDrawable TileMe = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.tile));
El backrepeat.xml anterior es buggy
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/tile" android:tileMode="repeat" android:dither="true" />
Parece que algunas personas están interesadas en hacer esto en una vista, en el método onDraw. El siguiente código ha funcionado para mí:
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; }
<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" >
Esto funcionó bien para mí. No tuve que crear el mapa de bits por separado. Utilicé el atributo tileMode en el diseño.
Sólo tiene que poner esta línea de códigos en el 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);
Si desea repetir el fondo sólo verticalmente, puede establecer el ancho de su diseño como "wrap_content", mientras que si desea configurar el fondo para que se repita horizontalmente, establezca la altura como "wrap_content". Si tanto la altura como el ancho se ajustan a "fill_parent", entonces se teñirá en las direcciones X e Y.
Por ejemplo, el código siguiente repetirá su fondo verticalmente:
<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>
/* 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); }
}
- Pausar error de GC después de la actualización de Android 4.4.2
- Confundido sobre cómo usar CouchDB en Android