AndroidのBitmapのロードについて

このQ&Aのポイント
  • OPENGLESで文字の描画を行っている際に、アプリが警告なしで強制終了する問題が発生しています。
  • バイト数を抑えると一応ロードは可能ですが、文字を動的に表示することができません。
  • 解決策をご教授いただける方がいらっしゃいましたら、お知恵をお貸しください。
回答を見る
  • ベストアンサー

AndroidのBitmapのロードについて

はじめまして 今OPENGLESで文字の描画を行っているのですが、何度も読み込んで解放してを繰り返していると なぜかアプリが警告なしで 強制終了します。 バイト数を抑えると一応ロードは可能なのですが、これでは文字を動的に表示できなくてこまっています。 以下がロードする文字列です public void textload(String[] str,int x,int y, int size){ // Log.v("デバッグ","ロード開始"); GL10 gl = glGraphics.getGL(); int[] textureIds = new int[1]; gl.glGenTextures(1, textureIds, 0); textureId = textureIds[0]; /** * 空のビットマップを作成し、そこへ文字を書き込むことでGL上に描画を行う。 */ //ビットマップの数値を計算 Log.v("デバッグ","ビットマップロード"); bitmap = Bitmap.createBitmap(640,480, Config.ARGB_4444); canvas = new Canvas(bitmap); Paint paint = new Paint(); Log.v("デバッグ","完了"); paint.setColor(Color.WHITE); paint.setStyle(Style.FILL); paint.setTextSize(size); canvas.drawColor(0); for(int i=0;i<str.length;i++){ if(str[i] != null){ canvas.drawText(str[i], x, y + size*(i+1), paint); } } width = bitmap.getWidth(); height = bitmap.getHeight(); gl.glEnable(GL10.GL_TEXTURE_2D); Log.v("デバッグ","ビットマップをtexImage2Dに"); // ! テクスチャ情報の設定 gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); //setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); Log.v("デバッグ","完了"); // ! bitmapを破棄 Log.v("デバッグ","解放処理開始"); if(bitmap !=null){ bitmap.recycle(); bitmap = null; } Log.v("デバッグ","解放処理完了"); //Log.v("デバッグ","ロード完了"); } かなり困っています・・・ どなたかご教授お願いします・・・

  • Java
  • 回答数2
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
noname#177743
noname#177743
回答No.2

OpenGLの部分は、Javaのコードというより、実際にはOpenGL側で動いているものなわけですから、OpenGLの作法にしたがって書く必要があるようですね。 私もあまりよく知らないのですが、glGenTexturesでロードしたテクスチャーは、利用が終わった後、glDeleteTexturesで破棄しなければいけないようです。どのタイミングでテクスチャーを利用しているのかわからないのですが、そのへんの破棄する処理は問題ないのでしょうか。

その他の回答 (1)

  • chie65535
  • ベストアンサー率43% (8519/19367)
回答No.1

>canvas = new Canvas(bitmap); >Paint paint = new Paint(); 明示的にdeleteしてないけど大丈夫? 関数を抜けるときに自動デストラクタが呼ばれるとは思うけど、確保されたリソースの廃棄まで保証されてたっけ? 面倒でも、newしたなら明示的にdeleteする習慣を付けた方がいい。

関連するQ&A

  • Androidアプリ実行エラー2

    Androidアプリ実行エラー ソースはこちらです。 package com.example.sudoku; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Paint.FontMetrics; import android.graphics.Paint.Style; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.animation.AnimationUtils; public class PuzzleView extends View { private static final String TAG = "Sudoku"; private float width; private float height; private int selX; private int selY; private final Rect selRect = new Rect(); private final Game game; public PuzzleView(Context context) { super(context); this.game = (Game) context; setFocusable(true); setFocusableInTouchMode(true); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { width = w / 9f; height = h / 9f; getRect(selX, selY, selRect); Log.d(TAG, "onSizeChanged: width " + width + ", height" + height); super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { //背景色の描画 Paint background = new Paint(); background.setColor(getResources().getColor( R.color.puzzle_background)); canvas.drawRect(0, 0, getWidth(), getHeight(), background); //盤面を描画する //枠線の色を定義する Paint dark = new Paint(); dark.setColor(getResources().getColor(R.color.puzzle_dark)); Paint hilite = new Paint(); hilite.setColor(getResources().getColor(R.color.puzzle_hilite)); Paint light = new Paint(); light.setColor(getResources().getColor(R.color.puzzle_light)); //マス目を区切る線 for (int i = 0; i < 9; i++) { canvas.drawLine(0, i * height, getWidth(), i * height, light); canvas.drawLine(0, i * height + 1, getWidth(), i * height + 1, hilite); canvas.drawLine(i * width, 0, i * width, getHeight(), light); canvas.drawLine(i * width + 1, 0, i * width + 1, getHeight(), hilite); } //3*3を区切る線 for (int i = 0; i < 9; i++) { if(i % 3 != 0) continue; canvas.drawLine(0, i * height, getWidth(), i * height, dark); canvas.drawLine(0, i * height + 1, getWidth(), i * height + 1, hilite); canvas.drawLine(i * width, 0, i * width, getHeight(), dark); canvas.drawLine(i * width + 1, 0, i * width + 1, getHeight(), hilite); } //数値を描画する Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG); foreground.setColor(getResources().getColor(R.color.puzzle_foreground)); foreground.setStyle(Style.FILL); foreground.setTextSize(height * 0.75f); foreground.setTextScaleX(width / height); foreground.setTextAlign(Paint.Align.CENTER); //マスの中央に数字を描く FontMetrics fm = foreground.getFontMetrics(); //x軸方向でセンタリングする。中央のx座標に揃える float x = width / 2; // float y = height / 2 - (fm.ascent + fm.descent) / 2; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { canvas.drawText(this.game.getTileString(i, j),i * width + x, j * height + y, foreground); } } //ヒントを描画する //選択されたマスを描画する } private void getRect(int x, int y, Rect rect) { rect.set((int) (x * width), (int) (y * height), (int) (x * width + width), (int) (y * height + height)); } } ログはこちらです。 ご回答をよろしくお願いします。 http://okwave.jp/qa/q8272113.html

  • C言語のOpenGLで複数のテクスチャをロード方法

    こんにちは、 よく探してたが、 C言語のOpenGLで一つだけじゃなくて複数のテクスチャをロードする方法は? 見つかったコードは 「一つだけのテクスチャをロードする」 ーーーーーーーーーーー void LoadGLTextures() { // Load Texture Image *image1; // allocate space for texture image1 = (Image *) malloc(sizeof(Image)); if (image1 == NULL) { printf("Error allocating space for image"); exit(0); } if (!ImageLoad("Data/01.bmp", image1)) { exit(1); } // Create Texture glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); // 2d texture (x and y size) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // scale linearly when image bigger than texture glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // scale linearly when image smalled than texture // 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, // border 0 (normal), rgb color data, unsigned byte data, and finally the data itself. glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->data); }; ーーーーーーーーーーー お願いします

  • package com.rensyu;コメントを入れて欲しいのですが…

    package com.rensyu;コメントを入れて欲しいのですが… import java.util.Calendar; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; public class rensyu extends Activity { Thread drawThread; class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { Bitmap osb; Canvas osc; public MySurfaceView(Context context) { super(context); getHolder().addCallback(this); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d("TEST", "surfaceChanged"); } @Override public void surfaceCreated(final SurfaceHolder holder) { Log.d("TEST", "surfaceCreated"); final Paint paint = new Paint(); paint.setColor(Color.RED); paint.setAntiAlias(true); paint.setTextSize(24); final Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.icon); drawThread = new Thread() { public void run() { try { while (true) { Canvas canvas = holder.lockCanvas(); if (osb == null) { osb = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.RGB_565); osc = new Canvas(osb); } osc.drawColor(Color.WHITE); Calendar cal = Calendar.getInstance(); String s = String.format("%02d:%02d:%02d.%03d", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND)); osc.drawText(s, 0, paint.getTextSize(), paint); osc.drawBitmap(bitmap, 0, paint.getTextSize(), null); canvas.drawBitmap(osb, 0, 0, null); holder.unlockCanvasAndPost(canvas); Thread.sleep(10); } } catch (Exception e) { } } }; drawThread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.d("TEST", "surfaceDestroyed"); } }

    • ベストアンサー
    • Java
  • androidの円(circle)を連続で出したい

    android初心者です。 androidの円(circle)を連続で出したいソースを作成していますがうまくいきません。 現在のソースではランダムで座標を取得することは出来ますが表示されません。 for文for(i=0;i<100;i++)で作成してみましたが、100回終わるまで円が表示されません。 以下が自分で作成してみたソースです。 どなたか詳しい方教えてください。 public class Balltataki extends Activity { int ran_width; int ran_height; Paint paint; boolean running=true; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); getWindow().setFormat(PixelFormat.TRANSLUCENT); setContentView(new BallView(this)); class BallView extends View { int flag=1; public BallView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { while(running==true){ ran_width = (int)(Math.random()*getWidth()); ran_height = (int)(Math.random()*getHeight()); Log.i("tag","ran_w:"+ran_width); Log.i("tag","ran_h:"+ran_height); paint=new Paint(); paint.setAntiAlias(true); paint.setStrokeWidth(1); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.argb(255, 255, 255, 255)); canvas.drawCircle(ran_width,ran_height,60,paint); try { Thread.sleep(100); } catch (Exception e) {} } } } }

  • Bitmap表示について WIN32

    「猫でもわかるwindowsプログラミング 第4版」を参考にして、ビットマップを表示するプログラムを作っています。 開発環境はVisual Studio Express 2015(Visual C++)です。 読み込んだビットマップを表示させようと、下記のように(本の内容をそっくりそのまま)コードとリソースを書いてみたのですがデバッグすると何も表示されないウィンドウが出てしまいます。 メッセージボックスで確かめてみると、 ビットマップリソースを読み込んだ際、hBmpにNULLが返っていました。 コードもリソースも本の通りに書いたので間違いはないと思います。 となると、うまくいかない理由はリソースとビットマップをプロジェクトに追加させるまでの過程にあると考えます。 本で扱っている環境はVisual c++ 2010 だったのですが、リソースの追加に関してバージョンの差が関係しているのでしょうか? リソースの追加に関してはネットや本にたくさん説明がありますが、それらの通り書いてもうまくいきません。 どうか、リソースのプロジェクトへの追加方法を教えていただけないでしょうか。 また、ソースコード・リソースに関して間違いがあるのならばアドバイスもらえるとありがたいです。 // ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc, hdc_mem; PAINTSTRUCT ps; HBITMAP hBmp; BITMAP bmp_info; int w, h; switch (msg) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // ビットマップリソース「MYBMP」を読み込む hBmp = LoadBitmap(hInst, TEXT("MYBMP")); // ビットマップの情報を取得し、幅と高さを変数に保管 GetObject(hBmp, (int)sizeof(BITMAP), &bmp_info); w = bmp_info.bmWidth; h = bmp_info.bmHeight; // メモリデバイスコンテキストを作成 hdc_mem = CreateCompatibleDC(hdc); // メモリデバイスコンテキストにビットマップを選択 SelectObject(hdc_mem, hBmp); // ビットマップを転送 BitBlt(hdc, 0, 0, w, h, hdc_mem, 0, 0, SRCCOPY); StretchBlt(hdc, w, 0, w * 2, h * 2, hdc_mem, 0, 0, w, h, SRCCOPY); DeleteDC(hdc_mem); // メモリデバイスコンテキストを破棄 DeleteObject(hBmp); // ビットマップオブジェクトを破棄 EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } //リソース MYBMP BITMAP "bitmap1.bmp"

  • Androidアプリ開発 画像の回転について

    CANVASに画像を表示し、その画像を回転させるようにしたいのですが、どうにもうまくいかなくて困っています。 画像の中心を軸に回転させたいと思って以下のように実装してみたのですが、うまくいきません。 //////////////////////////////以下抜粋//////////////////////////////// Matrix matrix; // Bitmap のサイズの取得 int width = bmp.getWidth(); int height = bmp.getHeight(); matrix = new Matrix(); // 画像の中心を軸に回転させるようにする(ここがうまくいっていないっぽい・・・) matrix.postRotate(5.0f, width / 2.0f, height / 2.0f); // 回転させた画像を生成する bmp2 = Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, true); // CANVASに画像を描画する canvas.drawBitmap(bmp2 , 10.0f, 10.0f, paint); ////////////////////////////////////////////////////////////////////// 上記のコードで画像自体は回転するのですが、中心軸がずれてしまっているようです。 画像のサイズは横15ピクセル、縦15ピクセルとなっております。 また、matrix.postRotateの前でmatrix.postTranslate()にて軸を設定してみたのですが、 これもうまくいきませんでした。 きれいに画像を回転させるにはどのようにすればよいか、わかる方いましたら教えて いただけないでしょうか?

    • ベストアンサー
    • Java
  • ポインタの配列

    int str[10]; int i; for(i=0;i<10;i++){ printf("str[%d]...%p",i,&str[i]); } だと配列ですから連続したアドレスが得られますが、 int *str[10]; int i; for(i=0;i<10;i++){ printf("*str[%d]...%p",i,&*str[i]); } だと不連続なアドレスが得られます。なぜでしょうか?なんとなく連続になりそうな気がしますが。

  • このプログラムのどこを直せばいいんでしょうか?

    いま、文字列strの中に文字cが含まれている個数を表示するプログラムを作っているんですが、下のように作っても、上手く行きません。 どこをどう直せばいいのか教えてください! #include <stdio.h> int str_chnum (const char str[],int d) { int i=0; int sum=0; while(str[i]!=0){ if(str[i]==d ){ sum++; } i++; } return(sum); } int main(void) { int c; char str[128]; puts("put sentence..."); scanf("%s",str); puts("search character..."); scanf("%d",&c); printf("there are %d %ds in this sentence.",str_chnum(str,c),c); return(0); }

  • マクロに関して

    C言語・C++初心者です。 マクロにて、printfをレベル分けして出力したいと思っております。 下記のようにレベルを1,2に区分して、マクロを呼出して、printf上にそのレベルを出力させたいという意向です。頭ではこうしたいというものはまとまっておりますが、いざソースに起こすと、コンパイルエラーとなります。 そもそもの記述方法が検討違いなのかと思いますが、なかなかうまくいきません。 大変申し訳ございませんが、ご教授よろしくお願いいたします。 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #include <stdio.h> // デバッグレベル1 #define DEBUGLV1(str) printf("LV[%d]:%s",1,str) // デバッグレベル2 #define DEBUGLV2(str) printf("LV[%d]:%s",2,str) int main() {  //-- 変数の宣言 --------------------  int iCnt; // ループカウンタt  //-- 変数の初期化 ------------------  iCnt = 0;  // ループ  for(iCnt=0; iCnt<2; iCnt++)  {   if(iCnt == 0)   {    DEBUGLV1("LV1LOG:iCnt[%d]\n", iCnt);   }   else   {    DEBUGLV2("LV2LOG:iCnt[%d]\n", iCnt);   }  }  return 0; } +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  • CImage GetBitsメソッドについて

    はじめまして質問させて頂きたい事がございます。 VC++ 2005 MFCを使用しております。 ビットマップ画像からCImageを作成し、 GetBits()を使用してポインタから直接RGB値を取得したと考えております。 MSDNには ------------------------------------------ 取得したポインタと GetPitch の戻り値を使用すると、 イメージ内のピクセルを個別に指定して変更できます。 ------------------------------------------ と書いてありますが、よく分かりませんでした。 ためしに4*4ピクセルのビットマップ画像をLoadして 以下のように実装してみました。 ---------------------------------------------- //ピッチ取得 int pit = m_image.GetPitch(); //バイト数取得 int byt = m_image.GetBPP(); //ポインタ取得 int* rgb; rgb = (int*)m_image.GetBits(); CString str; str.Format(_T("%d, "), GetRValue(rgb[0])); ::TRACE(str); str.Format(_T("%d, "), GetGValue(rgb[0])); ::TRACE(str); str.Format(_T("%d, "), GetBValue(rgb[0])); ::TRACE(str); ---------------------------------------------- ピッチがマイナスで戻ってきたので 左下隅を起点とする逆方向 (下から上) にrgb[0]からはいってると 解釈したのですが、正常な値(画像ソフトの値)が取得できませんでした。 どなたかお詳しい方がおりましたら ご教授お願いいたします。 お手数ではございますが サンプルコードを記載していただけるとありがたいです。 以上になります。 ご回答よろしくお願いいたします。

専門家に質問してみよう