[Android]"Bitmap too large to be uploaded into a texture"の対処方法


Androidで画像ビューアーの開発を行っていたときに、以下のエラーが表示され画像が表示できないことがありました。

W/OpenGLRenderer(3136): Bitmap too large to be uploaded into a texture (1685x2049, max=2048x2048)

この件について調べたのですが、Android4以降はビデオアクセラレーションを標準で使用し、端末が設定しているテクスチャの最大サイズの制限を受けるとのことでした。
Androidは、OSとして2048x2048以上をサポートするようになっているらしく、2048x2048以下に画像をすることで問題なく動作するようです。
しかし、これでは、大きいサイズの画像を表示できなくなってしまいます。
そのため、プログラムで動的に最大サイズを調べる必要があります。
この方法は、以下の2つがありました。
①カスタムViewを作成し、onDrawイベントでCanvasから最大サイズを取得する
②OpenGLから最大サイズを取得する
両方ともひと手間必要となります。
コードは以下となります。
①カスタムViewを作成し、onDrawイベントでCanvasから最大サイズを取得する

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
public class ViewBmpSizeDetector extends View {
private static String TAG = "ViewBmpSizeDetecter";
public interface IViewBmpSizeDetector{
public void onDetectMaxBitmapSize(int width, int height);
}
public int mMaxWidth = 0;
public int mMaxHeight = 0;
public IViewBmpSizeDetector mCallback;
public ViewBmpSizeDetector(Context context) {
this(context, null);
}
public ViewBmpSizeDetector(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 描画処理を記述
@Override
protected void onDraw(Canvas canvas) {
mMaxWidth = canvas.getMaximumBitmapWidth();
mMaxHeight = canvas.getMaximumBitmapHeight();
if(mCallback != null){
mCallback.onDetectMaxBitmapSize(mMaxWidth, mMaxHeight);
}
}
}

②OpenGLから最大サイズを取得する

public static int getMaxTextureSize() {
// Safe minimum default size
final int IMAGE_MAX_BITMAP_DIMENSION = 2048;
// Get EGL Display
EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
// Initialise
int[] version = new int[2];
egl.eglInitialize(display, version);
// Query total number of configurations
int[] totalConfigurations = new int[1];
egl.eglGetConfigs(display, null, 0, totalConfigurations);
// Query actual list configurations
EGLConfig[] configurationsList = new EGLConfig[totalConfigurations[0]];
egl.eglGetConfigs(display, configurationsList, totalConfigurations[0], totalConfigurations);
int[] textureSize = new int[1];
int maximumTextureSize = 0;
// Iterate through all the configurations to located the maximum texture size
for (int i = 0; i < totalConfigurations[0]; i++) {
// Only need to check for width since opengl textures are always squared
egl.eglGetConfigAttrib(display, configurationsList[i], EGL10.EGL_MAX_PBUFFER_WIDTH, textureSize);
// Keep track of the maximum texture size
if (maximumTextureSize < textureSize[0])
maximumTextureSize = textureSize[0];
}
// Release
egl.eglTerminate(display);
// Return largest texture size found, or default
return Math.max(maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION);
}






0 件のコメント :

コメントを投稿