Camera 相機(jī)實(shí)踐(基于UTS組件插件)

一、SurfaceView容器

碰到的問(wèn)題:無(wú)法基于容器的鏡像翻轉(zhuǎn)

1.1、創(chuàng)建容器對(duì)象(index.vue 文件中)

NVLoad() : LinearLayout {
    //必須實(shí)現(xiàn)(必須創(chuàng)建一個(gè)容器)
    let contentLayout = new LinearLayout(this.$androidContext);
    contentLayout.setOrientation(LinearLayout.VERTICAL);

    // 創(chuàng)建按鈕對(duì)象
    this.getCamera().forEach((button) => {
        contentLayout.addView(button as Button);
    })
    
    // 創(chuàng)建surfaceView容器
    surfaceView = new SurfaceView(this.$androidContext);
    let layoutParams = ViewGroup.LayoutParams(
        500,
        600
    )
    
    contentLayout.addView(textureView, layoutParams)
    
    return contentLayout;
}


methods: {
    getCamera() : Button[] {
        const numberOfCameras = Camera.getNumberOfCameras(); // 獲取攝像頭個(gè)數(shù)
        const cameraList : Button[] = [];
        for (let i = 0; i < numberOfCameras; i++) { // 從創(chuàng)建對(duì)應(yīng)的按鈕
            let button = new Button(this.$androidContext)
            button.setText(`攝像頭${i}`);
            button.setTag("centerButton");
            button.setOnClickListener(new ButtonClickListsner(i));
            cameraList.push(button);
        };
        
        return cameraList;
    }
}

1.2、創(chuàng)建點(diǎn)擊事件

class ButtonClickListsner extends View.OnClickListener {
        cameraId = 0
        constructor(id : number) {
            super();
            this.cameraId = id;
        }
        override onClick(v ?: View) {
            console.log(this.cameraId)
            openCamera(this.cameraId)
        }
}

1.3、打開(kāi)對(duì)應(yīng)攝像頭


function openCamera(id: any) {
    if (camera !== null) {
        (camera as Camera).stopPreview();
        (camera as Camera).release();  // 釋放攝像頭
        camera = null;
    }
    
    try {
        camera = Camera.open(id as Int);
        (camera as Camera).setPreviewDisplay((surfaceView as SurfaceView).getHolder());
        (camera as Camera).setDisplayOrientation(0); // 設(shè)置旋轉(zhuǎn)角度 0 90 180 270
        (camera as Camera).startPreview(); // 啟動(dòng)預(yù)覽
    } catch (e) {
            console.error(e)
    }
}

1.4、完整代碼

<template>
    <view class="defaultStyle"></view>
</template>

<script lang="uts">
    import View from 'android.view.View'
    import Button from 'android.widget.Button'
    import LinearLayout from 'android.widget.LinearLayout';
    import Camera from "android.hardware.Camera";
    import SurfaceView from 'android.view.SurfaceView';
    import ViewGroup from "android.view.ViewGroup";
    import Surface from "android.view.Surface";
    
    let surfaceView : SurfaceView | null = null;
    let camera : Camera | null = null;
    
    class ButtonClickListsner extends View.OnClickListener {
        cameraId = 0
        constructor(id : number) {
            super();
            this.cameraId = id;
        }
        override onClick(v ?: View) {
            console.log(this.cameraId)
            openCamera(this.cameraId)
        }
    }
    
    function openCamera(id: any) {
        if (camera !== null) {
            (camera as Camera).stopPreview();
            (camera as Camera).release();  // 釋放攝像頭
            camera = null;
        }
    
        try {
            camera = Camera.open(id as Int);
            (camera as Camera).setPreviewDisplay((surfaceView as SurfaceView).getHolder());
            (camera as Camera).setDisplayOrientation(0); // 設(shè)置旋轉(zhuǎn)角度 0 90 180 270
            (camera as Camera).startPreview(); // 啟動(dòng)預(yù)覽
        } catch (e) {
            console.error(e)
        }
    }
    
    export default {
        name: "camera-temps1",
        data() {
            return {}
        },
        
        NVLoad() : LinearLayout {
            //必須實(shí)現(xiàn)(必須創(chuàng)建一個(gè)容器)
            let contentLayout = new LinearLayout(this.$androidContext);
            contentLayout.setOrientation(LinearLayout.VERTICAL);

            // 創(chuàng)建按鈕對(duì)象
            this.getCamera().forEach((button) => {
                contentLayout.addView(button as Button);
            })
    
            // 創(chuàng)建surfaceView容器
            surfaceView = new SurfaceView(this.$androidContext);
            let layoutParams = ViewGroup.LayoutParams(
                500,
                600
            )
    
            contentLayout.addView(textureView, layoutParams)
    
            return contentLayout;
        },
        
        methods: {
            getCamera() : Button[] {
                const numberOfCameras = Camera.getNumberOfCameras(); // 獲取攝像頭個(gè)數(shù)
                const cameraList : Button[] = [];
                for (let i = 0; i < numberOfCameras; i++) { // 從創(chuàng)建對(duì)應(yīng)的按鈕
                    let button = new Button(this.$androidContext)
                    button.setText(`攝像頭${i}`);
                    button.setTag("centerButton");
                    button.setOnClickListener(new ButtonClickListsner(i));
                    cameraList.push(button);
                };
        
                return cameraList;
            }
        }
    }
}
</script>

二、TextureView(容器)

<template>
    <view class="defaultStyle">

    </view>
</template>
<script lang="uts">
    import View from 'android.view.View'
    import Button from 'android.widget.Button'
    import LinearLayout from 'android.widget.LinearLayout';
    import Camera from "android.hardware.Camera";
    import SurfaceView from 'android.view.SurfaceView';
    import ViewGroup from "android.view.ViewGroup";
    import TextureView from "android.view.TextureView";


    let camera : Camera | null = null;
    let textureView : TextureView | null = null;

    class PreviewCallback extends Camera.PreviewCallback {
        constructor() { super() }
        override onPreviewFrame(data : ByteArray, camera : Camera) {
            console.log(data)
        }
    }

    class ButtonClickListsner extends View.OnClickListener {
        cameraId = 0
        constructor(id : number) {
            super();
            this.cameraId = id;
        }
        override onClick(v ?: View) {
            console.log(this.cameraId)
            openCamera(this.cameraId)
        }
    }


    function openCamera(id : any) {
        if (camera !== null) {
            (camera as Camera).stopPreview();
            (camera as Camera).release();
            camera = null;
        }

        try {
        
            camera = Camera.open(id as Int);    
            // 設(shè)置鏡像
            (textureView as TextureView).setRotationY((180 as Number).toFloat());
            (camera as Camera).setPreviewTexture((textureView as TextureView).getSurfaceTexture());
            // 設(shè)置旋轉(zhuǎn)方向   
            (camera as Camera).setDisplayOrientation(0);
            (camera as Camera).startPreview();  
        } catch (e) {
            console.error(e)
        }
    }




    export default {
        name: "camera-temps1",
        data() {
            return {}
        },
        NVLoad() : LinearLayout {
            //必須實(shí)現(xiàn)  
            let contentLayout = new LinearLayout(this.$androidContext);
            contentLayout.setOrientation(LinearLayout.VERTICAL);
            
            // 添加按鈕
            this.getCamera().forEach((button) => {
                contentLayout.addView(button as Button);
            })
            
            // TextureView 中this.$androidContext 必須加 !號(hào)
            textureView = new TextureView(this.$androidContext!);
            
            let layoutParams = ViewGroup.LayoutParams(
                500,
                600
            );
            contentLayout.addView(textureView, layoutParams);
            
            return contentLayout;
        },

        methods: {          
            getCamera() : Button[] {
                const numberOfCameras = Camera.getNumberOfCameras();
                const cameraList : Button[] = [];
                for (let i = 0; i < numberOfCameras; i++) {
                    let button = new Button(this.$androidContext)
                    button.setText(`攝像頭${i}`);
                    button.setTag("centerButton");
                    button.setOnClickListener(new ButtonClickListsner(i))
                    cameraList.push(button)
                }
                
                return cameraList;
            }
        }
    }
</script>

<style>
    .defaultStyle {
        width: 750rpx;
        height: 240rpx;
        background-color: red;
    }
</style>

三、權(quán)限請(qǐng)求(index.uts)

import Manifest from "android.Manifest";
import Surface from "android.view.Surface";
import Camera from "android.hardware.Camera";
export function getquanxian() { 
    let permissionNeed = [Manifest.permission.CAMERA];

    UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, permissionNeed, function (allRight : boolean, _ : string[]) {
        console.log("用戶同意了權(quán)限", allRight)
    }, function (_ : boolean, _ : string[]) {
        console.log("用戶拒絕了部分權(quán)限:")
    })

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 上一篇文章介紹了如何調(diào)用系統(tǒng)相機(jī)進(jìn)行拍照裁剪等功能,一般情況下這些已經(jīng)能滿足我們的需求了。但是在有些場(chǎng)景和特...
    Smashing丶閱讀 67,905評(píng)論 20 219
  • 和你一起終身學(xué)習(xí),這里是程序員 Android 經(jīng)典好文推薦,通過(guò)閱讀本文,您將收獲以下知識(shí)點(diǎn): 一、 Surfa...
    程序員Android1閱讀 8,076評(píng)論 0 10
  • 前言 上一篇文章介紹了如何調(diào)用系統(tǒng)相機(jī)進(jìn)行拍照裁剪等功能,一般情況下這些已經(jīng)能滿足我們的需求了。但是在有些場(chǎng)景和特...
    LiChengZe_Blog閱讀 6,929評(píng)論 0 2
  • 前言 在上一篇文章中給小伙伴們介紹了進(jìn)行Camera開(kāi)發(fā)需要了解的知識(shí)點(diǎn),如果你還沒(méi)有看過(guò)的話,建議先去看上一篇文...
    LiChengZe_Blog閱讀 1,553評(píng)論 1 1
  • 背景 機(jī)緣巧合,需要自定義相機(jī),幾日折騰下來(lái),對(duì)相機(jī)開(kāi)發(fā)有了一定認(rèn)識(shí),做個(gè)小結(jié)。 既然是自定義相機(jī),在設(shè)想里,相機(jī)...
    MxsQ閱讀 2,861評(píng)論 0 11

友情鏈接更多精彩內(nèi)容