[英]Draw large bitmaps in Android
我不知道這個問題是否得到了回答。 至少我沒有找到答案。
所以這是一件事情:我正在Android上制作一些以太空為主題的2D游戲,並且正在屏幕尺寸= 2560x1600的模擬器上對其進行測試。 在這個游戲中,有一個太空飛船在飛的領域。 當然,它(一個字段)必須具有高分辨率的美麗背景。 我的背景圖片的分辨率為4500x4500。 我想使圖像相對於相機運動沿相反的方向運動,因此這就是為什么我不能使用小的靜態圖像的原因。 當時該圖像的一部分是可見的:
當我嘗試繪制時,我得到fps = 1-2(當然,由於圖像尺寸太小):
canvas.drawBitmap(getBigImage(), -x, -y, null);
/* getBigImage() method does nothing but returning
a Bitmap object (no calculation or decoding is performing in there) */
我試圖從較大的圖像中裁剪出所需的圖像,但fps仍然很低:
Bitmap b = Bitmap.createBitmap(getBigImage(), x, y, sw, sh);
canvas.drawBitmap(b, 0, 0, null);
如何繪制高fps的大位圖?
嘗試
drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
它從源圖像獲取一個像素的矩形,以在畫布上顯示一個矩形。 我做滾動游戲時發現速度更快。
我想了很多,想出了一個將輸入位圖分成小塊並將其保存到數組的想法。 所以現在要繪制該位圖,我要做的就是繪制可見的塊。
圖片:
黑色大矩形表示輸入位圖,綠色矩形表示視口,紅色矩形表示繪制的可見塊
我寫了一個可以完成所有工作的對象(我還沒有檢查它的錯誤:/)。 我已經對其進行了測試,它以〜45 fps的速度繪制了3000x3000位圖。 我認為這種方式非常有效。 該對象本身可能需要進一步開發,但是我認為此功能足以滿足我的需求。 希望能幫助到某人:)
PS https://stackoverflow.com/a/25953122/6121671-將其用於啟發:)
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
public final class DividedBitmap {
private final Bitmap[][] mArray; // array where chunks is stored
private final int mWidth; // original (full) width of source image
private final int mHeight; // original (full) height of source image
private final int mChunkWidth; // default width of a chunk
private final int mChunkHeight; // default height of a chunk
/* Init */
public DividedBitmap(Bitmap src) {
this(new Options(src, 100, 100));
}
public DividedBitmap(Options options) {
mArray = divideBitmap(options);
mWidth = options.source.getWidth();
mHeight = options.source.getHeight();
mChunkWidth = options.chunkWidth;
mChunkHeight = options.chunkHeight;
}
/* Getters */
public int getWidth() {
return mWidth;
}
public int getHeight() {
return mHeight;
}
public Bitmap getChunk(int x, int y) {
if (mArray.length < x && x > 0 && mArray[x].length < y && y > 0) {
return mArray[x][y];
}
return null;
}
/* Methods */
/**
* x, y are viewport coords on the image itself;
* w, h are viewport's width and height.
*/
public void draw(Canvas canvas, int x, int y, int w, int h, Paint paint) {
if (x >= getWidth() || y >= getHeight() || x + w <= 0 || y + h <= 0)
return;
int i1 = x / mChunkWidth; // i1 and j1 are indices of visible chunk that is
int j1 = y / mChunkHeight; // on the top-left corner of the screen
int i2 = (x + w) / mChunkWidth; // i2 and j2 are indices of visible chunk that is
int j2 = (y + h) / mChunkHeight; // on the right-bottom corner of the screen
i2 = i2 >= mArray.length ? mArray.length - 1 : i2;
j2 = j2 >= mArray[i2].length ? mArray[i2].length - 1 : j2;
int offsetX = x - i1 * mChunkWidth;
int offsetY = y - j1 * mChunkHeight;
for (int i = i1; i <= i2; i++) {
for (int j = j1; j <= j2; j++) {
canvas.drawBitmap(
mArray[i][j],
(i - i1) * mChunkWidth - offsetX,
(j - j1) * mChunkHeight - offsetY,
paint
);
}
}
}
/* Static */
public static Bitmap[][] divideBitmap(Bitmap bitmap) {
return divideBitmap(new Options(bitmap, 100, 100));
}
public static Bitmap[][] divideBitmap(Options options) {
Bitmap[][] arr = new Bitmap[options.xCount][options.yCount];
for (int x = 0; x < options.xCount; ++x) {
for (int y = 0; y < options.yCount; ++y) {
int w = Math.min(options.chunkWidth, options.source.getWidth() - (x * options.chunkWidth));
int h = Math.min(options.chunkHeight, options.source.getHeight() - (y * options.chunkHeight));
arr[x][y] = Bitmap.createBitmap(options.source, x * options.chunkWidth, y * options.chunkHeight, w, h);
}
}
return arr;
}
public static final class Options {
final int chunkWidth;
final int chunkHeight;
final int xCount;
final int yCount;
final Bitmap source;
public Options(Bitmap src, int chunkW, int chunkH) {
chunkWidth = chunkW;
chunkHeight = chunkH;
xCount = ((src.getWidth() - 1) / chunkW) + 1;
yCount = ((src.getHeight() - 1) / chunkH) + 1;
source = src;
}
public Options(int xc, int yc, Bitmap src) {
xCount = xc;
yCount = yc;
chunkWidth = src.getWidth() / xCount;
chunkHeight = src.getHeight() / yCount;
source = src;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.