Kanade Labo

かなで研究所

Android Studio カメラアプリ作成その12(カメラ表示7)

こんにちは かなで です。

前回までのお話。

カメラが映った!(偽物だけどね)

前回映った映像をアニメーションGIFにしてみました。

ちょっと荒いですが、少しグネ~っと動いてるのがわかりますか?

実はこの映像はAndroid Studioが準備した「カメラで写せと言われたらこれを使う」という設定がされているためです。

なので、これが表示されているということは、アプリとしては、ちゃんと「カメラプレビュー」ができていることになります。

ただ、言ってるように実際のカメラ映像ではないですね。

一応これを簡単に変更できたので、ここで紹介させていただきます。

まず、最初にエミュレータを落とします。

自分はいつも、電源ボタンを長押しして、「Power off」を選択しています。(たぶんちゃんとした方法があるんでしょうが)

次に、ツールからAVD Managerを開いて、

開いた「Android Virtual Device Manager」から、使用しているエミュレータの逆三角を押して、「Edit」を選びます。

「Virtual Device Configuration」が開いたら「Show Advanced Settings」を押します。

そして、Camera→Back→VirtualSceneとなっているのを「Webcam0」に変更します。

VirturlSceneが先ほどの家の中っぽい画像のことで、

Webcam0がPCについてるカメラの事ですね。PCによっては名前が変わるんだと思います。

ちなみにBackじゃなくてFrontはどうなの?というところですが、

        val cameraSelector : CameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()

この「LENS_FACING_BACK」という部分で背面カメラ(Back)のことを指すという設定になってるようです。

※ここでいう背面ってのは「Android」の背面のことであって、「PC」の背面じゃないので間違わないように

では設定が終わりましたので、再生ボタンで起動してみます。

どうでしょう。手近にあったキティちゃんにご登場いただきました(笑

ちゃんとカメラ映像が映ってますね!

やっとのことで、「カメラ映像を表示する」という目的を達成することが出来ました。

画面サイズが小さいの話とか、横向きに移っちゃってるところとかは、これからまた調べていきたいと思います。

それではここまでのコードをまとめて書いておきます

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:layout_width="729dp"
        android:layout_height="194dp"
        tools:layout_editor_absoluteX="1dp"
        tools:layout_editor_absoluteY="1dp"
        tools:ignore="MissingConstraints">
        <androidx.camera.view.PreviewView
            android:id="@+id/viewFinder"
            android:layout_width="729dp"
            android:layout_height="194dp"/>
    </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt

package net.kanalabo.cam

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleOwner
import com.google.common.util.concurrent.ListenableFuture
import androidx.camera.camera2.Camera2Config

//class MainActivity : AppCompatActivity() {
//    override fun onCreate(savedInstanceState: Bundle?) {
//        super.onCreate(savedInstanceState)
//        setContentView(R.layout.activity_main)
//    }
//}

class MainActivity : AppCompatActivity() {
    private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider>
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            val cameraProvider = cameraProviderFuture.get()
            bindPreview(cameraProvider)
        }, ContextCompat.getMainExecutor(this))
    }
    private fun bindPreview(cameraProvider : ProcessCameraProvider) {
        val preview : Preview = Preview.Builder()
            .build()

        val cameraSelector : CameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()
        val kanadeFinder: PreviewView = findViewById(R.id.viewFinder)
        preview.setSurfaceProvider(kanadeFinder.surfaceProvider)

        var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview)
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.kanalabo.cam">

    <uses-permission android:name="android.permission.CAMERA" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Cam">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

次回はカメラサイズをぴったりフィットさせたいですね。

最後までお読みいただきありがとうございました。
気になることがあったら、コメント頂けると嬉しいです。
自主学習も兼ねて記事にするかもしれません。

-AndroidStudio