質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.95%

グローバル変数の取得が一度しか出来ない

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 702

score 6

 前提・実現したいこと

Javaで、Androidのカメラプレビューを用いたアプリを作っています。
機能としては輝度値を取得し、一番明るい範囲を描画するものです。

グローバル変数を用いて、
明るい範囲をCanvasのViewに紐付けたいのですが、
グローバル変数の変更に一度しか対応してくれません。

理想としては5秒ごとに、
一番明るい範囲をリアルタイムで描画出来るような状態なのですが、

最初に取得した部分しか描画されません。

CanvasBasicViewのgetInt()を用いた取得方法に、
何か問題があるのではとは思っております。

 発生している問題・エラーメッセージ

グローバル変数の取得が一度しか出来ない

※2/13 追記
CameraViewのcntsvとCommonのkeyyyが変化する処理がずっとループしており、
再度getInt()することが出来ない

 該当のソースコード

//描画するView
public class CanvasBasicView extends View
{
    Timer timer;
    Canvas canvas;
    Common common;
    int keymain;

    private Paint mPaint = new Paint()

    public CanvasBasicView(Context context){
        super(context);
        //インスタンス化
        timer = new Timer();
        common = (Common)context.getApplicationContext();
    }


    @Override
    public void onDraw(final Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setStyle(Paint.Style.STROKE)

        //タイマー機能
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                //ここでKeyを取得
                keymain = common.getInt();

                if(keymain==0){
                    canvas.drawCircle(300, 1200, 100, mPaint);
                }
                if(keymain==1){
                    canvas.drawCircle(900, 1200, 100, mPaint);
                }
                if(keymain==2){
                    canvas.drawCircle(300, 500, 100, mPaint);
                }
                if(keymain==3){
                    canvas.drawCircle(900, 500, 100, mPaint);
                }
            }
        },500,3000);
    }
}
//グローバル変数を扱うための、クラス
public class Common extends Application {

    private int keyfin=0;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    //keyの値を代入
    public void setInt(int keyyy) {
        keyfin=keyyy;
    }

    //keyの値を取得
    public int getInt() {
        return keyfin;
    }
}
public class CameraView extends SurfaceView
        implements SurfaceHolder.Callback, Camera.PreviewCallback {
    //カメラの縦横 640*480は標準的に動く
    private static final int PREVIEW_WIDTH = 640;
    private static final int PREVIEW_HEIGHT = 480;
    private static final int FRAME_WIDTH = 50;
    private static final int SCALE = 1;
    private static final int VIEW_POINTS = 200;
    private static final float PEN_WIDTH = 3.0F;
    private int mBufSize;
    private float[] mVal;
    private int mSamples;
    private int mTop;
    private int mStep;
    private Camera mCamera = null;
    private SurfaceHolder mHolder = null;
    private SurfaceTexture mSurfaceTexture = null;
    String bbb ="hello_world";
    int keyfin = 0;
    int cntsv ;
    Timer timer;


    Common common;
    public int coun = 0;
    public Paint paintf;

    public Activity activity;

    //CameraViewのメソッド
    public CameraView(Context context) {
        super(context);

        mHolder = getHolder();
        mHolder.addCallback(this);

        //ここでインスタンス化
        common = (Common)context.getApplicationContext();
        timer = new Timer();
    }

    //カメラ作成にはsurfaceが必要で、surfaceの作成
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub

        //getWidthは画面サイズ取得
        mBufSize = getWidth();
        mVal = new float[mBufSize];
        mStep = (mBufSize - FRAME_WIDTH * 2) / VIEW_POINTS;

        // カメラオープン(カメラのインスタンスを取得)
        mCamera = Camera.open();
        try {
                 mCamera.setPreviewDisplay(holder);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

        }
    }

    //surface変更時の処理
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // TODO Auto-generated method stub
        stopPreview();
        // プレビュー画面のサイズ設定
        Camera.Parameters params = mCamera.getParameters();
        params.setPreviewSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
       // params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        mCamera.setParameters(params);
        // プレビュー開始
        mTop = 0;
        mSamples = 0;
        startPreview();
    }

    //surface破棄時の処理
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        stopPreview();
        mCamera.release();
        mCamera = null;
    }

    //ここでdataを定義
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        // TODO Auto-generated method stub

        mVal[mSamples % mBufSize] = calcLuminance(data);

        //  else {
        mSamples++;
     //   drawLuminance();
    }

    // プレビュー開始
    private void startPreview() {
        mCamera.setPreviewCallback(this);
        mCamera.startPreview();
    }

    // プレビュー停止
    private void stopPreview() {
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
    }

    // 輝度値の計算 "n"を箱として10個作る
    float n[] = new float[10];

    private float calcLuminance(byte[] data) {
        //時間計測開始
        long start = System.currentTimeMillis();
        float sumVal1 = 0.0f;
        float sumVal2 = 0.0f;
        float sumVal3 = 0.0f;
        float sumVal4 = 0.0f;

        //cntはcountするだけのもの
        int cnt = 0;
        int cnt1 = 0;
        int cnt2 = 0;
        int cnt3 = 0;
        int cnt4 = 0;

        //この範囲からこの範囲での、輝度値を積分している
        for (int y = PREVIEW_HEIGHT / 4  ; y < PREVIEW_HEIGHT * 3 / 8 ; y++) {
            //widthを1/4(160)から3/4(480)まで回す
            for (int x = PREVIEW_WIDTH / 4; x < PREVIEW_WIDTH * 3 / 8; x++) {

                //1/4~3/4は範囲を設定しただけ(端末の大きさにより、変化するため)
                //sumValは、画素値の合計値

                sumVal1 = sumVal1 + (float) (data[y * PREVIEW_WIDTH + x] & 0xff);
                cnt1++;

            }
        }

        //2回目
        for (int y = PREVIEW_HEIGHT / 4  ; y < PREVIEW_HEIGHT * 3 / 8   ; y++) {
            for (int x = PREVIEW_WIDTH * 3 / 8; x < PREVIEW_WIDTH * 3 / 4; x++) {

                sumVal2 = sumVal2 + (float) (data[y * PREVIEW_WIDTH + x] & 0xff);
                cnt2++;

            }
        }

        //3回目
        for (int y = PREVIEW_HEIGHT * 3 / 8  ; y < PREVIEW_HEIGHT * 3 /4  ; y++) {
            for (int x = PREVIEW_WIDTH / 4; x < PREVIEW_WIDTH * 3 / 8; x++) {

                sumVal3 = sumVal3 + (float) (data[y * PREVIEW_WIDTH + x] & 0xff);
                cnt3++;

            }
        }

        //4回目
        for (int y = PREVIEW_HEIGHT * 3/ 8  ; y < PREVIEW_HEIGHT * 3 / 4  ; y++) {
            for (int x = PREVIEW_WIDTH *3 / 8; x < PREVIEW_WIDTH * 3 / 4; x++) {

                sumVal4 = sumVal4 + (float) (data[y * PREVIEW_WIDTH + x] & 0xff);
                cnt4++;

            }
        }

        //合計値を、平均化している
        sumVal1 = sumVal1/cnt1;
        sumVal2 = sumVal2/cnt2;
        sumVal3 = sumVal3/cnt3;
        sumVal4 = sumVal4/cnt4;

        //最大値を求めるコード
        float sumValarray[]={sumVal1,sumVal2,sumVal3,sumVal4};
        //とりあえず0を入れた
        float sumValmax=sumValarray[0];

        //sumValmaxを特定するループ
        for(int i=0;i<sumValarray.length;i++){
         if(sumValarray[i]>=sumValmax){
             sumValmax= sumValarray[i];
         //keyを取得するためのcntsv
             cntsv=i;
         }

//        グローバル変数のset
       common.setInt(cntsv);

}

 試したこと

Timerを用いて、一定時間ごとの処理

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • keicha_hrs

    2018/02/08 20:17

    提示されたコードにはCommon#setInt()を呼び出しているところが一箇所もないようですが、提示されていないところに存在するのでしょうか?

    キャンセル

回答 1

0

Common#setInt()を含むコードの提示までいただき、ありがとうございます。setInt()の方法に問題があるのではないかと思いましたが、新たに提示していただいたコードを見てもよくわかりませんでした。

Commonの作り方やset、getの方法自体に問題があるとは思えません。曲がりなりにも動作しているのであれば、AndroidManifest.xmlへの記述忘れということもないのでしょう。setInt()の行にLogを入れるなりブレークポイントを設定してデバッグするなりして、様々な値が引数として渡されていることを確認するより他はないかと思います。

役に立たない回答で申し訳ありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/13 11:42

    ご返信ありがとうございます。
    ブレークポイントでのデバックですと、CameraViewのcntsvとCommonのkeyyyが変わっていくのがずっとループしている状態でした。 
    ここのループがもしかしたら原因かもしれないので、引き続き原因を探してみます。

    拙いコードにも関わらず、回答していただき本当にありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.95%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る