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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

3915閲覧

android SurfaceViewからBitmapを取得する方法

sekaikan_ozaki

総合スコア65

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

1クリップ

投稿2019/12/16 06:49

編集2019/12/23 02:50

Windows10 HOME 64bit
Android Studio 3.5.2
デモ用端末OS:7.0 API 24

カメラで表示しているプレビューの最中にボタンを押して、表示中のプレビューのbitmapが取得できるようにしたいです。

いままで、プレビューをTextureViewを使って表示していたので、TextureViewの場合であれば、簡単にgetBitmap()で取得することができていました。

しかし今回、SurfaceViewを使っており、どうしてもBitmapが取得したい状況です。
SurfaceViewはgetBitmap()メソッドが存在しないようなので、別の方法でbitmapを取得できるのでしょうか?
あれば教えていただきたいです。
とにかくSurfaceViewのキャプチャ画像が取得できれば大成功です。

色々インターネットで検索してみましたが、良い解決策が見つかりませんでしたので、どなたかご教授いただければ嬉しいです。

以下に簡単なコードを載せます

java

1 2package com.example.textrecognizer; 3 4 5import android.content.Context; 6 7import android.graphics.Bitmap; 8import android.graphics.Canvas; 9import android.graphics.Rect; 10import android.support.annotation.NonNull; 11import android.support.v7.app.AppCompatActivity; 12import android.os.Bundle; 13import android.util.Log; 14import android.util.SparseArray; 15import android.view.SurfaceHolder; 16import android.view.SurfaceView; 17import android.view.View; 18import android.widget.Button; 19import android.widget.TextView; 20import com.google.android.gms.vision.CameraSource; 21import com.google.android.gms.vision.Detector; 22import com.google.android.gms.vision.text.TextBlock; 23import com.google.android.gms.vision.text.TextRecognizer; 24import java.io.FileOutputStream; 25import java.io.IOException; 26 27 28public class MainActivity extends AppCompatActivity { 29 30 31 private SurfaceView mCameraView; 32 private TextView mTextView; 33 private CameraSource mCameraSource; 34 private TextRecognizer textRecognizer; 35 private CameraPermission cameraPermission; 36 37 38 39 @Override 40 protected void onCreate(Bundle savedInstanceState) { 41 super.onCreate(savedInstanceState); 42 setContentView(R.layout.activity_main); 43 44 cameraPermission = new CameraPermission(this); 45 mCameraView = findViewById(R.id.cameraView); 46 mTextView = findViewById(R.id.text_view); 47 48 startCamera(); 49 50 Button button = (Button) findViewById(R.id.button); 51 button.setOnClickListener(new View.OnClickListener() { 52 @Override 53 public void onClick(View v) { 54 Log.d("debug", "ボタンをクリックしました"); 55 56 Canvas canvas = mCameraView.getHolder().lockCanvas(); 57 //別途BitmapとCanvasを用意する 58 Bitmap bmp = Bitmap.createBitmap(mCameraView.getWidth(), mCameraView.getHeight(), Bitmap.Config.ARGB_8888); 59 Canvas tmpCanvas = new Canvas(bmp); 60 //TODO tmpCanvasに対して描画処理を行う 61 Rect mScreenRect = new Rect(0, 0, mCameraView.getWidth(), mCameraView.getHeight()); 62 tmpCanvas.drawBitmap(bmp, null, mScreenRect, null); 63 mCameraView.getHolder().unlockCanvasAndPost(canvas); 64 65 } 66 }); // btnRead 67 68 } 69 70 // ファイルを保存 71 public void saveFile(String file, Bitmap bitmap) { 72 // try-with-resources 73 try (FileOutputStream fileOutputstream = openFileOutput(file, 74 Context.MODE_PRIVATE)) { 75 //bitmapをJpeg画像化 76 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputstream); 77 fileOutputstream.flush(); 78 } catch (IOException e) { 79 e.printStackTrace(); 80 } 81 } 82 83 84 /** 85 * Starts camera source after camera permission is granted 86 * 87 * @param requestCode 88 * @param permissions 89 * @param grantResults 90 */ 91 @Override 92 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 93 if (requestCode == cameraPermission.getCameraPermissionID()) { 94 95 if (cameraPermission.checkHasCameraPermission()) { 96 97 Log.i("onRequestResult", "Permission has been granted"); 98 try { 99 mCameraSource.start(mCameraView.getHolder()); 100 } catch (IOException e) { 101 e.printStackTrace(); 102 } 103 } 104 } 105 106 } 107 108 109 /** 110 * Gets TextBlock from TextRecognizer, set Text to TextView. 111 */ 112 private void setDataToTextView() { 113 114 textRecognizer.setProcessor(new Detector.Processor<TextBlock>() { 115 @Override 116 public void receiveDetections(Detector.Detections<TextBlock> detections) { 117 final SparseArray<TextBlock> items = detections.getDetectedItems(); 118 119 if (items.size() != 0) { 120 mTextView.post(new Runnable() { 121 @Override 122 public void run() { 123 124 //Gets strings from TextBlock and adds to StringBuilder 125 final StringBuilder stringBuilder = new StringBuilder(); 126 for (int i = 0; i < items.size(); i++) 127 stringBuilder.append(items.valueAt(i).getValue()); 128 129 mTextView.setText(stringBuilder.toString()); 130 131 } 132 }); 133 } 134 } 135 136 @Override 137 public void release() { 138 } 139 }); 140 } 141 142 /** 143 * Init camera source with needed properties, 144 * then set camera view to surface view. 145 * 必要なプロパティでカメラソースを初期化し、 146 * カメラビューをサーフェスビューに設定します。 147 */ 148 private void startCamera() { 149 150 textRecognizer = new TextRecognizer.Builder(getApplicationContext()).build(); 151 152 if (textRecognizer.isOperational()) { 153 154 mCameraSource = new CameraSource.Builder(getApplicationContext(), textRecognizer) 155 .setFacing(CameraSource.CAMERA_FACING_BACK) 156 .setRequestedPreviewSize(1280, 1024) 157 .setAutoFocusEnabled(true) 158 .setRequestedFps(30.0f) 159 .build(); 160 161 //If permission is granted cameraSource started and passed it to surfaceView 162 mCameraView.getHolder().addCallback(new SurfaceHolder.Callback() { 163 @Override 164 public void surfaceCreated(SurfaceHolder holder) { 165 if (cameraPermission.checkHasCameraPermission()) { 166 167 try { 168 mCameraSource.start(mCameraView.getHolder()); 169 170 } catch (IOException e) { 171 e.printStackTrace(); 172 } 173 174 } else { 175 176 Log.i("surfaceCreated", "Permission request sent"); 177 cameraPermission.requestCameraPermission(); 178 } 179 Log.e(TAG, "surfaceCreated()"); 180 } 181 182 @Override 183 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 184 Log.e(TAG, "surfaceChanged()"); 185 186 } 187 188 @Override 189 public void surfaceDestroyed(SurfaceHolder holder) { 190 mCameraSource.stop(); 191 Log.e(TAG, "surfaceDestroyed()"); 192 } 193 }); 194 195 setDataToTextView(); 196 Log.e(TAG, "setDataToTextView()"); 197 198 } 199 } 200 201 @Override 202 public void onPause() { 203 super.onPause(); 204 } 205 206 207}

xml

1 2<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 xmlns:app="http://schemas.android.com/apk/res-auto" 6 android:orientation="vertical" 7 android:weightSum="10"> 8 9 <SurfaceView 10 android:id="@+id/cameraView" 11 android:scaleType="fitCenter" 12 android:layout_width="0dp" 13 android:layout_height="0dp" 14 app:layout_constraintBottom_toBottomOf="parent" 15 app:layout_constraintLeft_toLeftOf="parent" 16 app:layout_constraintRight_toRightOf="parent" 17 app:layout_constraintTop_toTopOf="parent" /> 18 19 <TextView 20 android:id="@+id/text_view" 21 android:layout_width="match_parent" 22 android:layout_height="50dp" 23 android:gravity="bottom" 24 android:textColor="@android:color/white" 25 android:textSize="20sp" 26 android:textStyle="bold" 27 app:layout_constraintLeft_toLeftOf="parent" 28 app:layout_constraintRight_toRightOf="parent" 29 app:layout_constraintTop_toTopOf="parent" /> 30 31 <Button 32 android:id="@+id/button" 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 app:layout_constraintBottom_toBottomOf="parent" 36 app:layout_constraintLeft_toLeftOf="parent" 37 app:layout_constraintRight_toRightOf="parent" /> 38 39 40</android.support.constraint.ConstraintLayout>

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

PixelCopy.request()
にて、可能なようです。

googel > pixelcopy.request example
https://www.javatips.net/api/android.view.pixelcopy

投稿2019/12/17 00:41

sugar_yas

総合スコア135

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sekaikan_ozaki

2019/12/18 00:12

回答ありがとうございます。 これはAPI24以上から使用できるメソッドのようですが、23以下でも使うことを想定していたので、別の方法はありませんでしょうか?
sekaikan_ozaki

2019/12/18 00:49

getDrawingCache()はすでに試してみましたが、真っ黒な画像になってしまいうまくいきませんでした。
sugar_yas

2019/12/18 05:34

う~ん、SurfaceViewの内部でLockCanvasへの描画内容を、自前でBitmapで保存しておくか、 スクリーンショットから切り取るくらいしか、思いつかないです。申し訳ないです。 https://akira-watson.com/android/screenshot.html
sekaikan_ozaki

2019/12/20 07:12

>SurfaceViewの内部でLockCanvasへの描画内容を、自前でBitmapで保存しておく こちらについて、もう少し詳しく教えていただけますでしょうか...?
sekaikan_ozaki

2019/12/23 00:09 編集

ちなみに以下の方法でも試してみましたが、真っ黒が画像として出力されました... Bitmap bmp = Bitmap.createBitmap(surfaceView.getWidth(), surfaceView.getHeight(), Bitmap.Config.ARGB_8888); // surfaceViewのサイズで Bitmap を作成 Canvas canvas = new Canvas(bmp); // bmp をターゲットにした Canvas を作成 surfaceView.draw(canvas); スクリーンショットについては、画面全体が抜けてしまうことと、パーミッション追加の関係で、今回は使用できなさそうです...
sugar_yas

2019/12/20 08:30

対象SurfaceView(=SurfaceViewを継承したクラスの内部に描画処理がある)としたときに、 メンバーとして、Bitmap bmpを保持しておき、 クラス内でgetHolder().lockCanvas()で取得したCanvasにdrawしている内容と同じことを、 自前のcanvas[Canvas canvas = new Canvas(bmp)]にもdrawすれば、Bitmapが取得でると思います。 もしくは、先にBitmapを作成し、getHolder().lockCanvas()へのdrawはBitmapを描画するなどで、対処されている方もいるようです。
sekaikan_ozaki

2019/12/23 02:48

返信ありがとうございます。 そういうやり方があるのですね。 ボタンを押した際に、ビットマップを取得したかったので、そのようにソースコードを編集してみました。 (↑の質問の方のソースコードを編集したものに変更しています。) エラーメッセージが出てしまい、 surfaceviewにアクセスできない状態になってしまいます。 これではbitmapの取得は難しいのでしょうか...
sugar_yas
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問