最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Maui Blazor 使用攝像頭實(shí)現(xiàn)代碼

 更新時(shí)間:2023年01月12日 10:20:53   作者:dotnet-simple  
由于Maui Blazor中界面是由WebView渲染,所以再使用Android的攝像頭時(shí)無法去獲取,因?yàn)樵臄z像頭需要綁定界面組件,這篇文章主要介紹了Maui Blazor 使用攝像頭實(shí)現(xiàn),需要的朋友可以參考下

由于Maui Blazor中界面是由WebView渲染,所以再使用Android的攝像頭時(shí)無法去獲取,因?yàn)樵臄z像頭需要綁定界面組件
所以我找到了其他的實(shí)現(xiàn)方式,通過WebView使用js調(diào)用設(shè)備攝像頭 支持多平臺(tái)兼容目前測試了Android 和PC 由于沒有ioc和mac無法測試 大概率是兼容可能需要?jiǎng)討B(tài)申請(qǐng)權(quán)限

1. 添加js方法

我們?cè)賥wwroot中創(chuàng)建一個(gè)helper.js的文件并且添加以下倆個(gè)js函數(shù)
index.html中添加<script src="helper.js"></script>引入js

/**
 * 設(shè)置元素的src
 * @param {any} canvasId canvasId的dom id
 * @param {any} videoId video的dom id
 * @param {any} srcId img的dom id
 * @param {any} widht 設(shè)置截圖寬度
 * @param {any} height 設(shè)置截圖高度
 */
function setImgSrc(dest,videoId, srcId, widht, height) {
    let video = document.getElementById(videoId);
    let canvas = document.getElementById(canvasId);
    console.log(video.clientHeight, video.clientWidth);
   
    canvas.getContext('2d').drawImage(video, 0, 0, widht, height);

    canvas.toBlob(function (blob) {
        var src = document.getElementById(srcId);
        src.setAttribute("height", height)
        src.setAttribute("width", widht);
        src.setAttribute("src", URL.createObjectURL(blob))
    }, "image/jpeg", 0.95);
}
/**
 * 初始化攝像頭
 * @param {any} src 
 */
function startVideo(src) {
    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {
            let video = document.getElementById(src);
            if ("srcObject" in video) {
                video.srcObject = stream;
            } else {
                video.src = window.URL.createObjectURL(stream);
            }
            video.onloadedmetadata = function (e) {
                video.play();
            };
            //mirror image
            video.style.webkitTransform = "scaleX(-1)";
            video.style.transform = "scaleX(-1)";
        });
    }
}

然后各個(gè)平臺(tái)的兼容

android:

Platforms/Android/AndroidManifest.xml文件內(nèi)容

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
	<application android:allowBackup="true" android:supportsRtl="true"></application>
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
	<uses-permission android:name="android.permission.INTERNET" />
	<!--相機(jī)權(quán)限-->
	<uses-permission android:name="android.permission.CAMERA" android:required="false"/>
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
	<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
	<!--相機(jī)功能-->
	<uses-feature android:name="android.hardware.camera" />
	<!--音頻錄制權(quán)限-->
	<uses-permission android:name="android.permission.RECORD_AUDIO" />
	<!--位置權(quán)限-->
	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
	
	<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
	<uses-feature android:name="android.hardware.location.gps" />

	<queries>
		<intent>
			<action android:name="android.intent.action.VIEW" />
			<data android:scheme="http"/>
		</intent>
		<intent>
			<action android:name="android.intent.action.VIEW" />
			<data android:scheme="https"/>
		</intent>
	</queries>
</manifest>

Platforms/Android/MainActivity.cs文件內(nèi)容

[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Platform.Init(this, savedInstanceState);
        // 申請(qǐng)所需權(quán)限 也可以再使用的時(shí)候去申請(qǐng)
        ActivityCompat.RequestPermissions(this, new[] { Manifest.Permission.Camera, Manifest.Permission.RecordAudio, Manifest.Permission.ModifyAudioSettings }, 0);
    }
}

MauiWebChromeClient.cs文件內(nèi)容

#if ANDROID
using Android.Webkit;
using Microsoft.AspNetCore.Components.WebView.Maui;

namespace MainSample;

public class MauiWebChromeClient : WebChromeClient
{
    public override void OnPermissionRequest(PermissionRequest request)
    {
        request.Grant(request.GetResources());
    }
}

public class MauiBlazorWebViewHandler : BlazorWebViewHandler
{
    protected override void ConnectHandler(Android.Webkit.WebView platformView)
    {
        platformView.SetWebChromeClient(new MauiWebChromeClient());
        base.ConnectHandler(platformView);
    }
}

#endif

MauiProgram.cs中添加以下代碼;如果沒有下面代碼會(huì)出現(xiàn)沒有攝像頭權(quán)限
具體在這個(gè) issue體現(xiàn)

#if ANDROID
        builder.ConfigureMauiHandlers(handlers =>
        {
            handlers.AddHandler<IBlazorWebView, MauiBlazorWebViewHandler>();
        });
#endif

以上是android的適配代碼 pc不需要設(shè)置額外代碼 ios和mac不清楚

然后編寫界面

@page "/" @*界面路由*@

@inject IJSRuntime JSRuntime @*注入jsRuntime*@

@if(OpenCameraStatus) @*在攝像頭沒有被打開的情況不顯示video*@
{
    <video id="@VideoId" width="@widht" height="@height" />
    <canvas class="d-none" id="@CanvasId" width="@widht" height="@height" />
}
<button @onclick="" style="margin:8px">打開攝像頭</button> 
@*因?yàn)閿z像頭必須是用戶手動(dòng)觸發(fā)如果界面是滑動(dòng)進(jìn)入無法直接調(diào)用方法打開攝像頭所以添加按鈕觸發(fā)*@
<button style="margin:8px">截圖</button> @*對(duì)視頻流截取一張圖*@

<img id="@ImgId" />

@code{
    private string CanvasId;
    private string ImgId;
    private string VideoId;
    private bool OpenCameraStatus;
    private int widht = 320;
    private int height = 500;

    private async Task OpenCamera()
    {
        if (!OpenCameraStatus)
        {
            // 由于打開攝像頭的條件必須是用戶手動(dòng)觸發(fā)如果滑動(dòng)切換到界面是無法觸發(fā)的
            await JSRuntime.InvokeVoidAsync("startVideo", "videoFeed");
            OpenCameraStatus = true;
            StateHasChanged();
        }
    }

    protected override async Task OnInitializedAsync()
    {
        // 初始化id
        ImgId = Guid.NewGuid().ToString("N");
        CanvasId = Guid.NewGuid().ToString("N");
        VideoId = Guid.NewGuid().ToString("N");
        await base.OnInitializedAsync();
    }

    private async Task Screenshot()
    {
        await JSRuntime.InvokeAsync<String>("setImgSrc", CanvasId,VideoId, ImgId, widht, height);
    }
}

然后可以運(yùn)行程序就可以看到我們的效果了

示例代碼:gitee github

到此這篇關(guān)于Maui Blazor 使用攝像頭實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Maui Blazor 攝像頭內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • Flyway的簡單介紹及使用詳解

    Flyway的簡單介紹及使用詳解

    這篇文章主要介紹了Flyway的簡單介紹及使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • leetcode刷題記錄(最新推薦)

    leetcode刷題記錄(最新推薦)

    本文給大家分享的leetcode刷題記錄包括矩陣置0、螺旋矩陣、旋轉(zhuǎn)圖像、搜索二維矩陣、反轉(zhuǎn)鏈表、回文鏈表,每道題目提供了解答方法和思路,感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • 一張圖告訴你計(jì)算機(jī)編程語言的發(fā)展歷史

    一張圖告訴你計(jì)算機(jī)編程語言的發(fā)展歷史

    這篇文章主要介紹了一張圖告訴你計(jì)算機(jī)編程語言的發(fā)展歷史,也可看作是計(jì)算機(jī)的發(fā)展歷史大事記,需要的朋友可以參考下
    2015-07-07
  • 微信支付--簽名錯(cuò)誤問題的解決方法

    微信支付--簽名錯(cuò)誤問題的解決方法

    這篇文章主要介紹了微信支付--簽名錯(cuò)誤問題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-07-07
  • 利用ChatGPT與MindShow制作一個(gè)PPT的方法詳解

    利用ChatGPT與MindShow制作一個(gè)PPT的方法詳解

    PPT制作是商務(wù)、教育和各種場合演講的重要組成部分,然而,很多人會(huì)花費(fèi)大量時(shí)間和精力在內(nèi)容生成和視覺設(shè)計(jì)方面,為了解決這個(gè)問題,我們可以利用兩個(gè)強(qiáng)大的工具——ChatGPT和MindShow,來提高制作PPT的效率,感興趣的同學(xué)可以參考閱讀
    2023-06-06
  • HTTP協(xié)議詳細(xì)介紹

    HTTP協(xié)議詳細(xì)介紹

    HTTP是訪問互聯(lián)網(wǎng)使用的核心通信協(xié)議,也是所有web應(yīng)用程序使用的通信協(xié)議。本文詳細(xì)介紹了HTTP協(xié)議,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Keras搭建Efficientdet目標(biāo)檢測平臺(tái)的實(shí)現(xiàn)思路

    Keras搭建Efficientdet目標(biāo)檢測平臺(tái)的實(shí)現(xiàn)思路

    EfficientNet模型具有很獨(dú)特的特點(diǎn),這個(gè)特點(diǎn)是參考其它優(yōu)秀神經(jīng)網(wǎng)絡(luò)設(shè)計(jì)出來的,本文以Efficientnet-B0和Efficientdet-D0為例,進(jìn)行Efficientdet的解析,感興趣的朋友一起看看吧
    2021-06-06
  • 使用roolup構(gòu)建你的lib(實(shí)現(xiàn)步驟)

    使用roolup構(gòu)建你的lib(實(shí)現(xiàn)步驟)

    大家都知道Rollup更加適合用于構(gòu)建lib 而 Webpack, Precel 更加適合開發(fā)應(yīng)用。本文,將結(jié)合一個(gè)簡單的例子說說如何使用Rollup構(gòu)建自己的lib,感興趣的朋友一起看看吧
    2021-08-08
  • 詳細(xì)講解HDFS的高可用機(jī)制

    詳細(xì)講解HDFS的高可用機(jī)制

    本文詳細(xì)講解了HDFS的高可用機(jī)制。如果namenode出現(xiàn)問題,整個(gè)HDFS集群將不能使用,HDFS高可用(HA)方案就是為了解決這個(gè)問題而產(chǎn)生的,讓我們一起來了解了解吧
    2021-08-08
  • GCC?指令詳解及動(dòng)態(tài)庫、靜態(tài)庫的使用方法

    GCC?指令詳解及動(dòng)態(tài)庫、靜態(tài)庫的使用方法

    GCC?是?Linux?下的編譯工具集,是「GNU?Compiler?Collection」的縮寫,包含?gcc、g++?等編譯器,這篇文章主要介紹了GCC?指令詳解及動(dòng)態(tài)庫、靜態(tài)庫的使用,需要的朋友可以參考下
    2022-10-10

最新評(píng)論

杨浦区| 托里县| 博兴县| 长白| 突泉县| 仪征市| 罗定市| 筠连县| 毕节市| 韶关市| 修水县| 灯塔市| 嘉义市| 东源县| 南靖县| 忻州市| 千阳县| 兴业县| 宁波市| 阿拉尔市| 泰来县| 海原县| 浦北县| 保定市| 通海县| 措美县| 肥城市| 西丰县| 黔江区| 石柱| 连州市| 曲周县| 安化县| 武安市| 政和县| 罗江县| 安国市| 金溪县| 会泽县| 玉龙| 光山县|