【OpenGL】Android端Camera與OpenGL融合顯示(AR技術基礎)
Android端Camera與OpenGL融合顯示(AR技術基礎)
import android.app.ActivityManager; import android.content.Context; import android.content.pm.ConfigurationInfo; import android.graphics.PixelFormat; import android.hardware.Camera; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.opengl.GLSurfaceView; import android.util.Log; import android.view.Display; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.Window; import android.view.WindowManager; import android.widget.FrameLayout; import android.hardware.Camera.Parameters; import android.provider.Settings.System; import android.app.Activity; import android.view.Display; import android.view.Menu; import android.view.Surface; import android.view.SurfaceHolder.Callback; import android.view.ViewGroup.LayoutParams; import java.io.IOException; public class MainActivity extends AppCompatActivity { private final int CONTEXT_CLIENT_VERSION = 1; private PreView mPreView; private GLSurfaceView mGLSurfaceView; FrameLayout frameLayout; private int mWidth = 0; private int mHeight = 0; private FrontCamera mFrontCamera = new FrontCamera(); private SurfaceView mSurface; private SurfaceHolder mHolder; private Context mContext; //private PreView preview; GLSurfaceView surfaceView; MyRendererPNG render; int width,height; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = this; //mPreView = (PreView)findViewById(R.id.surfaceView); //mGLSurfaceView = new GLSurfaceView ( this ); //requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); WindowManager wManager = (WindowManager)getSystemService(WINDOW_SERVICE); Display display = wManager.getDefaultDisplay(); width = display.getWidth(); height = display.getHeight(); setContentView(R.layout.activity_main); frameLayout = (FrameLayout)findViewById(R.id.frameView); /** * 先新增GLSurfaceView */ surfaceView = new GLSurfaceView(this); surfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); /** * Set the desired PixelFormat of the surface. The default is OPAQUE. When working with a SurfaceView, * this must be called from the same thread running the SurfaceView's window. */ surfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); render = new MyRendererPNG(); surfaceView.setRenderer(render); frameLayout.addView(surfaceView, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); /** * 再新增SurfaceView圖層 */ mSurface = new SurfaceView(this); mHolder = mSurface.getHolder(); mHolder.addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { mFrontCamera.stopCamera(); } @Override public void surfaceCreated(SurfaceHolder holder) { //初始化前置攝像頭 mFrontCamera.openCam(holder ,mContext); mFrontCamera.everyTime(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mFrontCamera.pingMuChange(); } }); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); frameLayout.addView(mSurface, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); } @Override protected void onResume() { // Ideally a game should implement onResume() and onPause() // to take appropriate action when the activity looses focus super.onResume(); } @Override protected void onPause() { // Ideally a game should implement onResume() and onPause() // to take appropriate action when the activity looses focus super.onPause(); } }
import android.app.Activity; import android.content.Context; import android.hardware.Camera; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import java.io.IOException; public class FrontCamera{ static final String TAG = "CameraTag"; public Camera mCamera; public byte[] mData = null; public int w = 0; public int h =0; int mCurrentCamIndex = 0; Context mContext; //初始化相機 public Camera initCamera() { int cameraCount = 0; Camera cam = null; Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); cameraCount = Camera.getNumberOfCameras(); for (int camIdx = 0; camIdx < cameraCount; camIdx++) { Camera.getCameraInfo(camIdx, cameraInfo); //在這裡開啟的是前置攝像頭,可修改開啟後置OR前置 if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { try { Log.i(TAG, "初始化相機 CameraIndex " + camIdx); cam = Camera.open(camIdx); mCurrentCamIndex = camIdx; } catch (RuntimeException e) { Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage()); } } } return cam; } /** * 停止相機 * * */ public void stopCamera() { if (mCamera != null) { mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); Log.i(TAG, "StopCamera: 停止預覽並釋放資源"); mCamera = null; } } /** * 旋轉屏幕後自動適配(若只用到豎的,也可不要) * 已經在manifests中讓此Activity只能豎屏了 * @param activity 相機顯示在的Activity * @param cameraId 相機的ID * @param camera 相機物件 */ public static void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) { Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } public void everyTime() { mCamera.setPreviewCallback(new Camera.PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) { mData = data; Camera.Size size = camera.getParameters().getPreviewSize(); w = size.width; h = size.height; } }); } public void openCam(SurfaceHolder holder, Context mContext) { this.mContext = mContext; if (mCamera == null) { mCamera = initCamera(); Log.i(TAG, "mCamera: " + mCamera.toString()); } try { //適配豎排固定角度 Log.i(TAG, "mCamera: " + mCamera.toString()); setCameraDisplayOrientation((Activity) mContext, mCurrentCamIndex, mCamera); mCamera.setPreviewDisplay(holder); Log.i(TAG, "開始預覽"); } catch (IOException e) { mCamera.release(); mCamera = null; } } public void pingMuChange() { Camera.Parameters parameters = mCamera.getParameters(); parameters.setPreviewSize(320,240); parameters.setPreviewFrameRate(15); parameters.setSceneMode(Camera.Parameters.SCENE_MODE_NIGHT); parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); //mCamera.setParameters(parameters); mCamera.startPreview(); } }
import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GLSurfaceView.Renderer; public class MyRendererPNG implements Renderer { float[] verteices = new float[] { 0.1f,0.6f,0.0f, -0.3f,0.0f,0.0f, 0.3f,0.1f,0.0f }; int[] colors = new int[] { 65535,0,0,0, 0,65535,0,0, 0,0,65535,0 }; FloatBuffer vBuffer = MemUtil.makeFloatBuffer(verteices); IntBuffer cBuffer = MemUtil.makeIntBuffer(colors); public MyRendererPNG () { } @Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -1.0f); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuffer); gl.glColorPointer(4, GL10.GL_FIXED, 0, cBuffer); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); gl.glFinish(); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); float ratio = (float)width/height; gl.glFrustumf(-ratio, ratio, -1, 1, 1, 9); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glDisable(GL10.GL_DITHER); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); gl.glClearColor(0, 0, 0, 0); gl.glShadeModel(GL10.GL_SMOOTH); gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL); } }
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
/**
* Created by duan on 2017.
*/
public class MemUtil {
public static FloatBuffer makeFloatBuffer(float[] arr){
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
public static IntBuffer makeIntBuffer(int[] arr){
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
IntBuffer fb = bb.asIntBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
}
Taily老段的微信公眾號,歡迎交流學習
相關推薦
【OpenGL】Android端Camera與OpenGL融合顯示(AR技術基礎)
Android端Camera與OpenGL融合顯示(AR技術基礎) import android.app.ActivityManager; import android.content.Context; import android.content.pm.Confi
【乾貨】Android studio教程與問題彙總
The LogCat window no longer switches to a different process when the current process dies (issue 161145 ) Prevent "StartupAbortedException" for the IDE wh
【Java】 大話資料結構(18) 排序演算法(5) (直接插入排序) 資料結構與演算法合集 資料結構與演算法合集
本文根據《大話資料結構》一書,實現了Java版的直接插入排序。 更多:資料結構與演算法合集 基本概念 直接插入排序思路:類似撲克牌的排序過程,從左到右依次遍歷,如果遇到一個數小於前一個數,則將該數插入到左邊所有比自己大的數之前,也就是說,將該數前面的所有更大的數字都後移一位,空出來的位置放入該數。
【JNI】 Android呼叫JNI的進階例項(攝像頭預覽資料轉碼RGB播放)
這裡要說下,儘量不要用Java寫編解碼的東西,就算你是大神,你寫的出來,但那也是不實用的,就像切西瓜一樣,拿一把削水果刀去切西瓜,肯定比不上用西瓜刀方便吧,還是老老實實寫個JNI呼叫得了,也不復雜C/C++方便的很,當然,這裡不是說Java不行,語言只是工具,做什
2017秋-軟件工程第七次作業(1)-【探路者】貪吃蛇阿爾法發布展示(視頻展示)
軟件工程 lin 使用 .html -1 target 背景音樂 targe 核心 Part One 【探路者】選題展示視頻鏈接: http://www.iqiyi.com/w_19ruzx6xud.html Part Two 【貪吃蛇】阿爾法發布視頻截圖 1視頻的前半部
【轉】PHP中的後期靜態綁定(Late Static Bindings )
mbo 代碼 當前 test num ngs color public name php5.3版本新增的靜態綁定的靜態綁定語法,也成為PHP的後期靜態綁定,如下 class A{ public static function func1(){ e
【轉】金蝶EAS BOS工作流開發(附帶JAVA指令碼)
目錄(?)[+] 流程配置基本知識及示例 重要概念 流程變數 任務輸入輸出 注意事項 基本流程的配置示例
【轉載】vscode佔滿cpu的解決方法(rg.exe佔用)
【轉載】VScode佔用cup100% – 作者:zhengrong__ 百度搜到的,真的太有用了。 最近遇到的問題,vscode一開電腦就開始卡,明明是新電腦。。。開啟工作管理員發現cpu佔用率幾乎100%,是3個rg.exe佔用的。百度了一下才找到方法。 在VScode中檔
【精華】PhalApi 2.x 新版本釋出流程(歡迎來開源)
當前,2.x新版本釋出的流程,主要如下。 重要的資訊 PhalApi 2.x Kernal核心包(底層程式碼在這裡):https://github.com/phalapi/kernal PhalApi 2.x 專案(直接可用於開發的專案):https://github.com/phalapi/p
【心得】Lattice和Xilinx工具關鍵特性對比(Diamond、ISE)
【根索引】 【索引】FPGA相關 背景 由於FPGA器件選型為Lattice的,所以由之前熟悉的ISE切換到Diamond,目前還在不斷適應中,有些過程體會,記錄下來供參考。按開發流程,講一些常用的特性進行對比,列舉如下: IP Core管理 Diamond初次見面的坑 內建邏輯分析儀(俗
【 FPGA 】FIR 濾波器之濾波器的係數資料(Filter Coefficient Data)
Filter Coefficient Data 濾波器係數使用副檔名為.coe的係數檔案提供給FIR編譯器。 這是一個ASCII文字檔案,帶有單行標題,用於定義用於係數資料的數字表示的基數,後跟係數值本身。 對於N抽頭濾波器,如圖3-36所示。 濾波器係數可以以整數的
【STM32】SPI的基本原理、庫函式(SPI一般步驟)
《STM32中文參考手冊V10》-第23章 序列外設介面SPI SPI的基本介紹 SPI的簡介 SPI,是英語Serial Peripheral interface的縮寫,顧名思義就是序列外圍裝置介面,是Motorola首先在其MC68HCXX系列處理器上定義
【解決】Centos7 離線安裝gcc-4.8.5(利用rpm包)
最近需要在Centos7 安裝gcc-4.8.5,但很不幸,環境沒有網路,因此只能手動下載回所有依賴,並依次安裝。 一開始我是不知道gcc-4.8.5有什麼依賴的,就到網上去找gcc-4.8.0等其他版本的依賴(因為找不到有講gcc-4.8.5的版本),然後再自己揣摩,但這樣效率很低
【Excel】五種方法新增打勾方框(其他符號差不多)
【Excel】五種方法新增打勾方框(其他符號差不多) office2013 方法一 ALT+9745 對應效果圖 按住ALT鍵不放,輸入9745四個數字,鬆開ALT鍵,即可。 這是一種符號輸入系統,不同的數字對應不同的符號 對應對映關係(連結來源:百
【WPF】後臺傳資料給前臺ListBox顯示(實時顯示)
因為需要實時接受資料並顯示到前臺ListBox中,所有使用下面這個方法。因為WPF前臺的樣式可以做的很炫,就用到style去寫樣式。 前臺: <Window.Resources> <
【動畫】簡易製作貝塞爾曲線動畫(JS+css3+canvas)
一些廢話(直接看程式碼的可跳過) 貝塞爾曲線:什麼是貝塞爾曲線?用過PS的就知道,那破鋼筆工具就是,什麼,沒用過?自行百度用法。 需要的工具 ctrl+c、ctrl+v 直接上程式碼 <!DOCTYPE html>
【題解】洛谷各種字串問題合集(持續更新中)
洛谷 P1449 字尾表示式 這道題需要手動模擬棧的操作。讀入字元,當字元不為終止字元@時,如果讀入的是數字就用now記錄下它的值,如果讀入的是 . 就將得到的數字值放到棧頂,並清空now。當讀到運算子時,就拿棧頂元素下面的第一個元素和棧頂元素進行加減乘除的操作,並將棧頂清
【Ionic】Ionic實現iOS與Android端程式碼『熱更新』與Android升級下載功能 ( v1.3.x版本 )
熱更新的好處 通常ionic原始碼可包括(HTML,JavaScript,CSS檔案和其他資源),往常我們必須通過提交程式到應用市場,經過漫長的稽核後才可讓使用者更新,每改動一個小地方都需要重新打新版本。 現在ionic通過使用cordova外掛cordov
【筆記】移動端H5數字鍵盤input type=number的處理(IOS和Android)
!= 字符串 文檔 代碼 || clear tcl rfi 導致 在Vue中的項目,基於VUX-UI開發,一個常見的需求: 1、金額輸入框 2、彈出數字鍵盤 3、僅支持輸入兩位小數,限制最大11位數,不允許0開頭 第一,首先想到額就是在VUX-UI中制定ty
【轉】文件下載之斷點續傳(客戶端與服務端的實現)
http協議 當前時間 end box [] ada demo 服務端 sem 【轉】文件下載之斷點續傳(客戶端與服務端的實現) 【轉】文件下載之斷點續傳(客戶端與服務端的實現) 前面講了文件的上傳,今天來聊聊文件的下載。 老規矩,還是從最簡單粗暴的開始。那麽多簡單算簡單