国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android 使用Camera2 API 和 GLSurfaceView實現(xiàn)相機預覽

這篇具有很好參考價值的文章主要介紹了Android 使用Camera2 API 和 GLSurfaceView實現(xiàn)相機預覽。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

GLSurfaceView 和 SurfaceView 是 Android 中用于顯示圖像的兩個視圖類,它們在實現(xiàn)方式和使用場景上有一些區(qū)別。

  • 實現(xiàn)方式:GLSurfaceView 基于 OpenGL ES 技術實現(xiàn),可以通過 OpenGL ES 渲染圖像。而 SurfaceView 則是通過基于線程的繪制方式,可以在獨立的線程中進行繪制操作。
  • 性能:由于 GLSurfaceView 使用了 OpenGL ES 技術,可以充分利用 GPU 進行圖像渲染,因此在處理復雜圖像和動畫時通常具有更好的性能。相比之下,SurfaceView 使用 CPU 進行圖像繪制,性能可能相對較低。
  • 使用場景:如果你需要進行復雜的圖形繪制、圖像處理或者動畫,那么 GLSurfaceView 是一個更好的選擇,因為它提供了強大的 OpenGL ES 功能支持。另外,GLSurfaceView 還可以與其他 OpenGL ES 相關的庫和工具進行集成。而 SurfaceView 在一些簡單的圖像展示場景中更常見,例如顯示圖片、播放視頻等。
  • 使用復雜度:由于 GLSurfaceView 使用了 OpenGL ES,因此它需要編寫著色器程序來進行圖像渲染,并且需要處理 OpenGL ES 相關的上下文管理。相對而言,SurfaceView 的使用相對簡單,只需繼承 SurfaceView 類并實現(xiàn)自定義的繪制邏輯即可。

需要注意的是,由于 GLSurfaceView 使用了 OpenGL ES 技術,它對開發(fā)者的要求更高,需要熟悉 OpenGL ES 相關的知識和編程技術。而 SurfaceView 在一些簡單的場景中更易于使用和理解。

總之,GLSurfaceView 適用于需要進行復雜圖形渲染和動畫的場景,而 SurfaceView 適用于一般的圖像展示和簡單的繪制需求。選擇哪個類取決于你的具體需求和技術能力。

  1. 在 AndroidManifest.xml 文件中添加相機權限:

    <uses-permission android:name="android.permission.CAMERA" />
    
  2. 創(chuàng)建相機預覽的布局

     <RelativeLayout 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=".CameraActivity">
        <android.opengl.GLSurfaceView
            android:id="@+id/glsurfaceview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>
    
  3. 創(chuàng)建相機預覽的 Activity,用于管理相機預覽和 OpenGL 繪制、

     package com.test.jnitest
     
     import android.Manifest
     import android.content.Context
     import android.content.pm.PackageManager
     import android.graphics.SurfaceTexture
     import android.hardware.camera2.CameraCaptureSession
     import android.hardware.camera2.CameraDevice
     import android.hardware.camera2.CameraManager
     import android.hardware.camera2.CaptureRequest
     import android.opengl.GLSurfaceView
     import android.os.Bundle
     import android.util.Size
     import android.view.Surface
     import android.view.WindowManager
     import androidx.appcompat.app.AppCompatActivity
     import androidx.core.app.ActivityCompat
     import com.test.jnitest.databinding.ActivityCameraBinding
     import java.util.*
     
     class CameraActivity : AppCompatActivity() {
         var mGLSurfaceView:GLSurfaceView?=null
         var mRenderer:CameraRenderer?=null
         var cameraManager:CameraManager?=null
         var mCameraDevice:CameraDevice?=null
         var mCaptureSession:CameraCaptureSession?=null
         var mRequestBuild:CaptureRequest.Builder?=null
         var size = Size(1920,1080)
         lateinit var mContext:Context
         lateinit var binding:ActivityCameraBinding
         override fun onCreate(savedInstanceState: Bundle?) {
             super.onCreate(savedInstanceState)
             binding = ActivityCameraBinding.inflate(layoutInflater)
             setContentView(binding.root)
             // 設置狀態(tài)欄透明
             window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
             //設置導航欄透明
             window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
             mContext = this
             mGLSurfaceView = binding.glsurfaceview
             mGLSurfaceView?.setEGLContextClientVersion(2)
             // 創(chuàng)建并設置相機渲染器
             mRenderer = CameraRenderer(mGLSurfaceView!!)
             mGLSurfaceView?.setRenderer(mRenderer)
             mGLSurfaceView?.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
             // 獲取攝像頭管理器
             cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
             if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                 this.requestPermissions(mutableListOf<String>(Manifest.permission.CAMERA).toTypedArray(),200)
                 return
             }
             cameraManager?.openCamera("5",mCameraStateCallback,null)
         }
     
         override fun onResume() {
             super.onResume()
             mGLSurfaceView?.onResume()
         }
     
         override fun onDestroy() {
             super.onDestroy()
             closeCamera()
         }
         // 相機狀態(tài)回調
         var mCameraStateCallback = object : CameraDevice.StateCallback() {
             override fun onOpened(p0: CameraDevice) {
                 mCameraDevice = p0
                 // 創(chuàng)建預覽會話
                 var surfaceTexture = mRenderer?.mSurfaceTexture
                 surfaceTexture?.setDefaultBufferSize(size.width,size.height)
                 var surface = Surface(surfaceTexture)
                 mRequestBuild = mCameraDevice?.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
                 mRequestBuild?.addTarget(surface)
                 val surfaces = Arrays.asList(surface)
                 mCameraDevice?.createCaptureSession(surfaces,mCaptureCallback,null)
             }
     
             override fun onDisconnected(p0: CameraDevice) {
                 p0.close()
             }
     
             override fun onError(p0: CameraDevice, p1: Int) {
                 p0.close()
             }
     
         }
         // 捕獲會話狀態(tài)回調
         var mCaptureCallback = object : CameraCaptureSession.StateCallback() {
             override fun onConfigured(p0: CameraCaptureSession) {
                 mCaptureSession = p0
                 mRequestBuild?.build()?.let { mCaptureSession?.setRepeatingRequest(it,null,null) }
             }
     
             override fun onConfigureFailed(p0: CameraCaptureSession) {
                 p0.close()
                 mCaptureSession = null
             }
     
         }
     
         // 關閉相機
         private fun closeCamera() {
             mCaptureSession?.close()
             mCaptureSession = null
             mCameraDevice?.close()
             mCameraDevice = null
         }
     }
    
  4. 創(chuàng)建相機渲染器,創(chuàng)建一個繼承自 GLSurfaceView.Renderer 的類,用于實現(xiàn) OpenGL 繪制和與相機交互的邏輯

     package com.test.jnitest
     
     import android.content.Context
     import android.graphics.SurfaceTexture
     import android.graphics.SurfaceTexture.OnFrameAvailableListener
     import android.opengl.GLES11Ext
     import android.opengl.GLES20
     import android.opengl.GLSurfaceView
     import java.nio.ByteBuffer
     import java.nio.ByteOrder
     import java.nio.FloatBuffer
     import javax.microedition.khronos.egl.EGLConfig
     import javax.microedition.khronos.opengles.GL10
     
     class CameraRenderer(var mGLSurfaceView: GLSurfaceView):GLSurfaceView.Renderer,OnFrameAvailableListener {
         //攝像頭圖像的紋理ID
         var textureId:Int = 0
         var mSurfaceTexture:SurfaceTexture?=null
         private val COORDS_PER_VERTEX = 2
         private val TEXTURE_COORDS_PER_VERTEX = 2
         //頂點著色器
         var vertexShaderCode = """attribute vec4 a_position;
             attribute vec2 a_textureCoord;
             varying vec2 v_textureCoord;
             void main() {
               gl_Position = a_position;
               v_textureCoord = a_textureCoord;
             }
             """
         // 片段著色器
         var fragmentShaderCode = """#extension GL_OES_EGL_image_external : require
             precision mediump float;
             uniform samplerExternalOES u_texture;
             varying vec2 v_textureCoord;
             void main() {
               gl_FragColor = texture2D(u_texture, v_textureCoord);
             }
             """
     
         //頂點坐標數(shù)據(jù),表示預覽圖像的位置和大小。
         private val VERTEX_COORDS = floatArrayOf(
             -1.0f, -1.0f,
             1.0f, -1.0f,
             -1.0f, 1.0f,
             1.0f, 1.0f
         )
         //紋理坐標數(shù)據(jù),表示攝像頭圖像在預覽區(qū)域的映射關系。
         private val TEXTURE_COORDS = floatArrayOf(
             0f, 1f,
             1f, 1f,
             0f, 0f,
             1f, 0f
         )
         //著色器程序的ID
         private var programId = 0
         //頂點屬性的句柄
         private var positionHandle = 0
         private var textureCoordHandle = 0
     
         init {
             textureId = createTexture()
             mSurfaceTexture = SurfaceTexture(textureId)
             mSurfaceTexture?.setOnFrameAvailableListener(this)
         }
     
         /**
          * 初始化OpenGL,并加載頂點著色器和片段著色器。通過編譯和鏈接著色器,創(chuàng)建著色器程序,并獲取頂點屬性的句柄。
          */
         override fun onSurfaceCreated(p0: GL10?, p1: EGLConfig?) {
             // 在此進行 OpenGL 環(huán)境初始化,如創(chuàng)建紋理、著色器程序等
             // 設置清空顏色緩沖區(qū)時的顏色值為黑色
             GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
             // 加載頂點著色器和片段著色器
             val vertexShader: Int = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
             val fragmentShader: Int = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
             // 創(chuàng)建著色器程序并將頂點著色器和片段著色器綁定到該程序上
             programId = GLES20.glCreateProgram()
             GLES20.glAttachShader(programId, vertexShader)
             GLES20.glAttachShader(programId, fragmentShader)
             // 鏈接著色器程序并檢查是否鏈接成功
             GLES20.glLinkProgram(programId)
             // 獲取頂點坐標屬性和紋理坐標屬性的位置
             positionHandle = GLES20.glGetAttribLocation(programId, "a_position")
             textureCoordHandle = GLES20.glGetAttribLocation(programId, "a_textureCoord")
             // 使用著色器程序
             GLES20.glUseProgram(programId)
         }
     
         override fun onSurfaceChanged(p0: GL10?, p1: Int, p2: Int) {
             // 在此響應 GLSurfaceView 尺寸變化,如更新視口大小等
             GLES20.glViewport(0, 0, p1, p2);
         }
     
         /**
          * 繪制每一幀,在此進行實際的繪制操作,如清屏、繪制紋理等
          */
         override fun onDrawFrame(p0: GL10?) {
             // 更新紋理圖像
             mSurfaceTexture?.updateTexImage();
             // 清空顏色緩沖區(qū)
             GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
             // 設置頂點坐標屬性并啟用
             GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, floatBufferFromArray(VERTEX_COORDS));
             GLES20.glEnableVertexAttribArray(positionHandle);
             // 設置紋理坐標屬性并啟用
             GLES20.glVertexAttribPointer(textureCoordHandle, TEXTURE_COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, floatBufferFromArray(TEXTURE_COORDS));
             GLES20.glEnableVertexAttribArray(textureCoordHandle);
             // 激活紋理單元0,并將當前紋理綁定到外部OES紋理目標
             GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
             GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
             // 繪制三角帶的圖元
             GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, VERTEX_COORDS.size / COORDS_PER_VERTEX);
         }
     
         /**
          * 創(chuàng)建攝像頭紋理
          */
         private fun createTexture(): Int {
             // 創(chuàng)建一個用于存儲紋理ID的數(shù)組
             val textureIds = IntArray(1)
             // 生成一個紋理對象,并將紋理ID存儲到數(shù)組中
             GLES20.glGenTextures(1, textureIds, 0)
             // 將當前紋理綁定到OpenGL ES的紋理目標(外部OES紋理)
             GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureIds[0])
             // 設置紋理S軸的包裹模式為GL_CLAMP_TO_EDGE,即超出邊界的紋理坐標會被截取到邊界上的紋素
             GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE)
             // 設置紋理T軸的包裹模式為GL_CLAMP_TO_EDGE
             GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE)
             // 設置紋理縮小過濾器為GL_NEAREST,即使用最近鄰采樣的方式進行紋理縮小
             GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST)
             // 設置紋理放大過濾器為GL_NEAREST
             GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST)
             return textureIds[0]
         }
         /**
          * 加載著色器,接受著色器類型和著色器代碼作為參數(shù),并將編譯后的著色器對象的ID返回
          * @param type 著色器類型,如GLES20.GL_VERTEX_SHADER或GLES20.GL_FRAGMENT_SHADER
          * @param shaderCode 著色器代碼
          * @return 著色器的ID
          */
         private fun loadShader(type: Int, shaderCode: String): Int {
             // 創(chuàng)建一個新的著色器對象
             val shader = GLES20.glCreateShader(type)
             // 將著色器代碼加載到著色器對象中
             GLES20.glShaderSource(shader, shaderCode)
             // 編譯著色器
             GLES20.glCompileShader(shader)
             return shader
         }
     
         private fun floatBufferFromArray(array: FloatArray): FloatBuffer? {
             val byteBuffer: ByteBuffer = ByteBuffer.allocateDirect(array.size * 4)
             byteBuffer.order(ByteOrder.nativeOrder())
             val floatBuffer: FloatBuffer = byteBuffer.asFloatBuffer()
             floatBuffer.put(array)
             floatBuffer.position(0)
             return floatBuffer
         }
     
         override fun onFrameAvailable(p0: SurfaceTexture?) {
             // 當相機有新的幀可用時回調,可以在這里進行一些處理
             mGLSurfaceView.requestRender()
         }
     }
    

通過以上步驟,你可以實現(xiàn)使用 Camera2 API 和 GLSurfaceView 預覽相機的功能。在 CameraActivity 中,我們通過 Camera2 API 打開相機并創(chuàng)建相機預覽會話,然后將相機預覽的 SurfaceTexture 傳遞給 CameraRenderer,在 CameraRenderer 的 onDrawFrame() 方法中繪制相機預覽幀的紋理內容。文章來源地址http://www.zghlxwxcb.cn/news/detail-704347.html

到了這里,關于Android 使用Camera2 API 和 GLSurfaceView實現(xiàn)相機預覽的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 嵌入式安卓開發(fā):使用Camera2獲取相機

    嵌入式安卓開發(fā):使用Camera2獲取相機

    從 Android 5.0 開始, Google 引入了一套全新的相機框架 Camera2(android.hardware.camera2) ,并且廢棄了舊的相機框架 Camera1(android.hardware.Camera) 。 Camera2相比于Camera的API不僅大幅提高了Android系統(tǒng)拍照的功能,還能支持RAW照片輸出,甚至允許程序調整相機的對焦模式、曝光模式、快

    2024年02月09日
    瀏覽(29)
  • 十分鐘實現(xiàn) Android Camera2 視頻錄制

    十分鐘實現(xiàn) Android Camera2 視頻錄制

    因為工作中要使用 Android Camera2 API ,但因為 Camera2 比較復雜,網上資料也比較亂,有一定入門門檻,所以花了幾天時間系統(tǒng)研究了下,并在 CSDN 上記錄了下,希望能幫助到更多的小伙伴。 上兩篇文章使用 Camera2 實現(xiàn)了相機預覽和拍照的功能,這篇文章我們接著上文,來實現(xiàn)

    2024年02月11日
    瀏覽(48)
  • Android studio Camera2實現(xiàn)的詳細流程

    前提 TextureView.SurfaceTextureListener是一個接口,用于監(jiān)聽TextureView中的SurfaceTexture的狀態(tài)更改。在使用相機時,您可以使用TextureView來顯示相機預覽。通過實現(xiàn)SurfaceTextureListener接口,您可以在SurfaceTexture準備好時開始相機預覽,并在SurfaceTexture銷毀時停止預覽。 注意 : 必須是在

    2024年02月05日
    瀏覽(22)
  • 【Camera2 教程二】Camera2相機打開和關閉接口調用詳細說明

    上一章《Camera2教程一》里我們介紹了一些 Camera2 的基礎知識,但是并沒有涉及太多的 API,從本章開始我們會開發(fā)一個具有完整相機功能的應用程序,并且將相機知識分成多個篇章進行介紹,而本章所要介紹的就是相機的開啟流程。 閱讀本章之后,你將學會以下幾個知識點:

    2024年04月25日
    瀏覽(35)
  • android camera系列(Camera1、Camera2、CameraX)的使用以及輸出的圖像格式

    android camera系列(Camera1、Camera2、CameraX)的使用以及輸出的圖像格式

    1.1.1、布局 1.1.2、實現(xiàn)預覽 Camera.open() 打開攝像頭 setPreviewDisplay 設置預覽展示的控件 startPreview 開始預覽 發(fā)現(xiàn)預覽是橫著的,需要使用 setDisplayOrientation 調整預覽圖像的方向 1.1.3、獲取攝像頭的原始數(shù)據(jù) setPreviewCallback 設置預覽數(shù)據(jù)的回調 2560*1440 默認返回圖像的分辨率 Image

    2024年02月21日
    瀏覽(29)
  • Android 11.0 MTK Camera2 設置默認拍照尺寸功能實現(xiàn)

    Android 11.0 MTK Camera2 設置默認拍照尺寸功能實現(xiàn)

    在11.0的系統(tǒng)rom定制化開發(fā)中,在mtk平臺的camera2關于拍照的一些功能修改中,在一些平臺默認需要設置最大的分辨率 來作為拍照的分辨率,所以就需要了解拍照尺寸設置流程,然后來實現(xiàn)相關的功能 如圖: Camera API中主要涉及以下幾個關鍵類 CameraManager:相機的實際管理者,調

    2024年01月21日
    瀏覽(126)
  • Android 12.0 MTK Camera2 設置默認拍照尺寸功能實現(xiàn)

    Android 12.0 MTK Camera2 設置默認拍照尺寸功能實現(xiàn)

    在12.0的系統(tǒng)rom定制化開發(fā)中,在mtk平臺的camera2關于拍照的一些功能修改中,在一些平臺默認需要設置最大的分辨率 來作為拍照的分辨率,所以就需要了解拍照尺寸設置流程,然后來實現(xiàn)相關的功能 如圖:

    2024年02月20日
    瀏覽(36)
  • Android 使用Camera1實現(xiàn)相機預覽、拍照、錄像

    Android 使用Camera1實現(xiàn)相機預覽、拍照、錄像

    本文介紹如何從零開始,在 Android 中實現(xiàn) Camera1 的接入,并在文末提供 Camera1Manager 工具類,可以用于快速接入 Camera1 。 Android Camera1 API 雖然已經被 Google 廢棄,但有些場景下不得不使用。 并且 Camera1 返回的幀數(shù)據(jù)是 NV21 ,不像 Camera2 、 CameraX 那樣,需要自己再轉一層,才能得

    2024年02月08日
    瀏覽(25)
  • Android Camera2(1)-Camera2在textureView中的預覽和拍照

    Android Camera2(1)-Camera2在textureView中的預覽和拍照

    解釋上訴示意圖,假如想要同時拍攝兩張不同尺寸的圖片,并且在拍攝過程中閃光燈必須亮起來。整個拍攝流程如下: 創(chuàng)建一個用于從 Pipeline 獲取圖片的 CaptureRequest。 修改 CaptureRequest 的閃光燈配置,讓閃光燈在拍照過程中亮起來。 創(chuàng)建兩個不同尺寸的 Surface 用于接收圖片

    2024年02月05日
    瀏覽(26)
  • Android 高通Camera2 Camera Device Close

    Android 高通Camera2 Camera Device Close

    ?1、很多人看到這個日志第一感覺可能覺得哪里沒有合理釋放,于是帶著這個思路去進行百度探索 2、一開始我去尋找?ImageReader.OnImageAvailableListener 這個問題 3、后面網上去尋找因為? Camera2最大連拍限制是 2 網上很多數(shù)包括Google相機源碼 需要單獨開個線程去處理圖片的邏輯

    2023年04月09日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包