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

flask 后端 + 微信小程序和網(wǎng)頁兩種前端:調(diào)用硬件(相機和錄音)和上傳至服務(wù)器

這篇具有很好參考價值的文章主要介紹了flask 后端 + 微信小程序和網(wǎng)頁兩種前端:調(diào)用硬件(相機和錄音)和上傳至服務(wù)器。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

選擇 flask 作為后端,因為后續(xù)還需要深度學(xué)習(xí)模型,python 語言最適配;而 flask 框架輕、學(xué)習(xí)成本低,所以選 flask 作為后端框架。

微信小程序封裝了調(diào)用手機硬件的 api,通過它來調(diào)用手機的攝像頭、錄音機,非常方便。

網(wǎng)頁端使用 JavaScript 調(diào)用則困難一些,走了很多彎路,在這里記錄下來。

前提:已經(jīng)配置好 python 環(huán)境、安裝了 flask;

flask 端

flask 的任務(wù)是收取前端傳來的文件,保存在本地。

from flask import Flask, request, jsonify, render_template
app = Flask(__name__)
app.config.from_object(__name__)
app.config["JSON_AS_ASCII"] = False  # 防止中文亂碼
app.json.ensure_ascii = False  # 防止中文亂碼
# 設(shè)置上傳文件夾
app.config['UPLOAD_FOLDER'] = r'D:\A_data_trans\test(改成你的位置)'

@app.route('/vqa', methods=['POST'])
def app_vqa():
    # 保存圖片
    img_file = request.files['img']  # 這里規(guī)定了前端傳圖片過來的時候,用的關(guān)鍵字是 'img',別的,比如 'image' 就會拿不到
    if img_file.filename == '':
        return jsonify({'error': 'No image'}), 400
    try:
        image_path = os.path.join(app.config['UPLOAD_FOLDER'], img_file.filename)
        img_file.save(image_path)
        log(f"save image: {image_path}")
    except Exception as e:
        return jsonify({'error': str(e)}), 500

    # 傳過來的就是文本
    question = request.form['question']  # 前端傳來的文本信息都是放在 form 中的

    # 預(yù)測答案
    try:
        answer = vqa(image_path, question)
        return jsonify(answer)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

# 接收文件的代碼,其實和上面長得一樣,略微有一 miu miu 區(qū)別
@app.route('/upload', methods=['POST'])
def app_upload_file():
    # 保存圖片
    img_file = request.files['img']
    if img_file.filename == '':
        return jsonify({'error': 'No image'}), 400
    try:
        image_path = os.path.join(app.config['UPLOAD_FOLDER'], img_file.filename)
        img_file.save(image_path)
        shutil.copy(image_path, os.path.join(os.path.dirname(__file__), 'static/show.jpg'))  # 用于展示在網(wǎng)頁上
        log(f"save image: {image_path}")
    except Exception as e:
        return jsonify({'error': str(e)}), 500

    try:
        # 傳過來的就是文本
        question = request.form['question']
    except:
        question = "請描述圖片內(nèi)容"
    return jsonify({"image": img_file.filename, "question": question})


@app.route('/upload/speech', methods=['POST'])
def recognize_speech():
    speech_file = request.files['speech']
    try:
        save_path = os.path.join(app.config['UPLOAD_FOLDER'], speech_file.filename)
        speech_file_path = os.path.join(app.config['UPLOAD_FOLDER'], save_path)
        speech_file.save(speech_file_path)
        # question = speech2txt(speech_file_path)
        # print('百度識別結(jié)果:', question)
    except Exception as e:
        return jsonify({'error': str(e)}), 500
    return jsonify({"speech": speech_file.filename})

微信小程序

微信小程序端的任務(wù)是,調(diào)用手機相機,把相機畫面展示給用戶,加一個按鈕,點擊按鈕拍照;另外一個按鈕,點擊可以把拍到的照片上傳。

wxml 中,放上一個 camera 用來顯示相機畫面;放上幾個 button,控制拍照、上傳。

<!--index.wxml-->
<scroll-view class="scrollarea" scroll-y type="list">
<!-- 相機畫面 -->
  <view class="my-container">
  <!-- 顯示相機畫面 -->
    <camera device-position="back" flash="off" binderror="error" style="width: 90%; height: 200px;"></camera>
  </view>
    <!-- 按鈕集合 -->
  <view class="my-container">
    <!-- 拍照、錄音、ocr 按鈕 -->
    <view class="button-row">
      <!-- 拍攝照片按鈕 -->
      <button class="btn-normal btn-large" hover-class="btn-pressed" bind:tap="takePhoto">拍攝圖片</button>
      <!-- 錄音得到 Question -->
      <button class="btn-normal btn-large" hover-class="btn-pressed" bind:touchstart="startRecord" bind:touchend="stopRecord">長按提問</button>
    </view>
    
    <!-- caption 和 vqa 按鈕 -->
    <view class="button-row">
      <!-- 發(fā)送預(yù)測 caption 請求 -->
      <button class="btn-normal btn-large" hover-class="btn-pressed" bind:tap="predCaption">描述圖片</button>
      <!-- 發(fā)送預(yù)測 vqa 請求 -->
      <button class="btn-normal btn-large" hover-class="btn-pressed" bind:tap="predVQA">回答問題</button>
    </view>
  </view>
</scroll-view>

用到的 wxss

/**index.wxss**/
page {
  height: 100vh;
  display: flex;
  flex-direction: column;
}
.scrollarea {
  flex: 1;
  overflow-y: hidden;
}

.btn-normal {
  margin-top: 10px;
  padding: 10px;
  background-color: rgb(252, 226, 230);
  color: black;
  border-radius: 0ch;
  border-color: brown;
  border-width: 1px;
  border-style: dotted;
  cursor: pointer;
  height: 70px;
  line-height: 50px;
  width: 90%;
  text-align: center;
  font-size: xx-large;
}

.btn-large {
  height: 300px;
}

.btn-pressed {
  background-color: rgb(202, 129, 140);
  color: rgb(82, 75, 75);
}

.btn-human {
  background-color: darkseagreen;
}

.btn-human-pressed {
  background-color:rgb(89, 141, 89);
  color: rgb(75, 82, 77);
}

button:not([size=mini]) {
  width: 90%;
}

.useGuide {
  margin-top: 10px;
  margin-bottom: 10px;
  width: 90%;
}

.text-question {
  margin-top: 10px;
  width: 90%;
}

.my-container {  
  display: flex;  
  flex-direction: column;  
  align-items: center;  
  justify-content: center;  
}  
  
.button-row {  
  display: flex;  
  justify-content: space-between;
  width: 90%;
}  

.donot-display {
  display: none;
}

js 部分。因為微信小程序給封裝得很好,所以基本沒有什么坑,按照這個寫就行,基本不出錯。要注意各種 success 方法,要用 success: (res) => {} 的寫法,不然在里面調(diào)用 this 是識別不到的。

Page({
	data: {
    serverUrl: 'http://改成你的',  // 服務(wù)器地址 
    photoData: '',  // 用戶拍攝的圖片
    speechData: '',  // 用戶提問的錄音文件
    textQuestion: '',  // 用戶提問文本
    recorderManager: null,
    textAnswer: '',  // vqa模型識別的文本
  },
  // 點擊拍照的方法在這里 (按鈕綁定在 wxml 就寫好了)
  takePhoto(e) {
    console.log("拍攝照片")
    const ctx = wx.createCameraContext();
    ctx.takePhoto({
      quality: 'low',
      success: (res) => {
        this.setData({
          photoData: res.tempImagePath  // res.tempImagePath 就可以拿到拍到的照片文件的 object url 地址,把這個地址傳給服務(wù)器,就可以把該文件傳給服務(wù)器
        });
      }
    });
  },
  // 控制長按錄音的代碼放在這里(按鈕綁定在 wxml 就寫好了)
  startRecord() {
    const recorderManager = wx.getRecorderManager();
    this.setData({ recorderManager });
	// 停止錄音的回調(diào)方法;在這里我加了調(diào)用百度語音 api 的東西,這部分會另外寫文詳說,這里只放出來一部分。所以這里沒有把錄音文件上傳,而是直接把語音識別的結(jié)果上傳文件夾
    recorderManager.onStop((res) => {
      console.log('recorder stop', res);
      this.setData({ speechData: res.tempFilePath });
      var baiduAccessToken = wx.getStorageSync('baidu_yuyin_access_token');
      // 讀取文件并轉(zhuǎn)為 ArrayBuffer
      const fs = wx.getFileSystemManager();
      fs.readFile({
        filePath: res.tempFilePath,
        success: (res) => {
          const base64 = wx.arrayBufferToBase64(res.data);
          wx.request({
            url: 'https://vop.baidu.com/server_api',
            data: {
              format: 'pcm',
              rate: 16000,
              channel: 1,
              cuid: 'sdfdfdfsfs',
              token: baiduAccessToken,
              speech: base64,
              len: res.data.byteLength,
            },
            method: "POST",
            header: {
              'content-type': 'application/json'
            },
            success: (res) => {
              wx.hideLoading();
              console.log("拿到百度語音api返回的結(jié)果")
              console.log(res.data);
              var baiduResults = res.data.result;
              console.log(baiduResults[0]);
              if (baiduResults.lenth == 0) {
                wx.showToast({
                  title: '未識別要語音信息!',
                  icon: 'none',
                  duration: 3000
                })} else {
                  this.setData({textQuestion: baiduResults[0]});
                }
            }
          })
        }
      })
    });
	// 這里才是控制錄音的參數(shù);微信小程序端可以設(shè)置這些錄音參數(shù),因為后面要調(diào)用百度語音識別 api,該 api 僅支持采樣率 16000 或 8000,對壓縮格式也有要求,所以錄音的時候要和 api 的要求保持一致
    recorderManager.start({
      format: 'PCM',
      duration: 20000,  // 最長支持 20s
      sampleRate:16000,
      encodeBitRate: 48000,
      numberOfChannels: 1,
      success: (res) => {
        console.log('開始錄音');
      },
      fail: (err) => {
        console.error('錄音失敗', err);
      }
    });
  },
  // 上傳的代碼放在這里
  predVQA() {
    if (this.data.photoData != '' && this.data.textQuestion != ''){
      console.log('send img' + this.data.photoData);
      wx.uploadFile({
        filePath: this.data.photoData,
        name: 'img',  // 文件對應(yīng) key,后端通過該 key 獲取文件;前后端注意保持一致
        url: this.data.serverUrl+'/vqa',
        formData: {'question': this.data.textQuestion},
        success: (res) => { 
          console.log('成功上傳'); 
          if (res.statusCode == 200) {
            var answer = res.data
            this.setData({ textAnswer: answer })
          } else { console.error(res) }
        },
        fail: (err) => { console.error('上傳失敗'); }
      })
    }
  },
})

網(wǎng)頁端的實現(xiàn)

網(wǎng)頁端就要復(fù)雜很多……掉過很多坑真的很難搞……(這里感謝 b站 up主 “前端石頭”,其中攝像頭拍照和錄音的 js 代碼參考了他的代碼)

而且這里有 2 個關(guān)鍵的問題:

  1. 關(guān)于視頻拍照:如果我把展示視頻流的那個控件隱藏掉,那拍出來的照片就是黑的。在微信小程序里就不會有這個問題。原因是,它拍照的原理是,通過 canvas 控件在 video 控件上截圖,如果你隱藏掉了,自然沒有圖可截,就是黑的。我找了很多資料,貌似沒有別的解決方法,所以我只能把視頻放很小,放角落里……
  2. 關(guān)于錄音:js 調(diào)用硬件就是很有限制。因為我后面想接百度語音識別的 api,該 api 僅支持采樣率 16000 或者 8000 的音頻,但是 js 默認(rèn)錄音采樣率 48000。我找到一些人說,在 constrains 里面?zhèn)鲄ⅲ?,不僅沒用,而且傳了之后會導(dǎo)致音頻損壞……然后問了 chatgpt,它說 js 很難變,只能你先錄好,然后通過代碼改采樣率。我試了直接傳音頻到服務(wù)器,然后 python 代碼改采樣率。但是 python 代碼改采樣率用的那個包,在 Windows 下運行會報錯,還得下一個軟件怎么怎么設(shè)置……就是很麻煩。所以,暫時沒有找到優(yōu)雅的解決方案。

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/full_button.css') }}" type="text/css">
</head>
<body>
    <div style="display: flex">
        <div>
            <video id="videoElement" autoplay="autoplay" muted="muted" style="width: 40px"></video>
            <img id="photo" alt="你的照片" src="" style="display: none">
        </div>
        <div id="answer" class="answer-text">答案等待中...</div>
    </div>

    <div class="button-grid">
        <button id="snapButton">拍攝照片</button>
        <button id="recorderButton">錄音</button>
        <button id="captionButton">描述圖片</button>
        <button id="vqaButton">回答問題</button>
    </div>

{#    <input type="text" id="textQuestion" placeholder="請輸入問題...">#}
    <script>
        var imageBlob = null;  // 拍攝的圖片
        var speechBlob = null;  // 提出的問題

        // 生成隨機文件名
        function randomFilename() {
            let now = new Date().getTime();
            let str = `xxxxxxxx-xxxx-${now}-yxxx`;
            return str.replace(/[xy]/g, function(c) {
                const r = Math.random() * 16 | 0;
                const v = c === 'x' ? r : (r & 0x3 | 0x8);
                return v.toString(16)
            })
        }
    </script>
    <script type="text/javascript" src="../static/js/user_camera.js"></script>
    <script type="text/javascript" src="../static/js/user_recorder.js"></script>
    <script>
        // 綁定 vqa 按鈕
        document.getElementById('vqaButton').onclick = function () {
            if (imageBlob == null) {
                alert('請先拍攝照片,再點擊“描述圖片”按鈕')
            } else {
                if (speechBlob == null) {
                    alert('您還沒有提問,請先點擊錄音按鈕錄音提問')
                } else {
                    let filename = randomFilename();
                    const speechFormData = new FormData();
                    // 注意,這里是第一個點:這里放進去的第一個參數(shù)是 key,后端就要通過這個 key 拿到文件。第二個參數(shù)是文件的二進制數(shù)據(jù),blob,別搞錯了!我會在 recorder.js 的代碼里給這個 speechBlob 賦值,總之它應(yīng)該是一個 Blob 對象。第三個參數(shù)是文件名,這個看你自己的需求。
                    speechFormData.append('speech', speechBlob, filename+'.wav');
                    // 這里是第二個點,把這個路徑換成你的位置。
                    // 而且我發(fā)現(xiàn),localhost 和 127.0.0.1 居然是有區(qū)別的,
                    // 我搞不太懂這二者的區(qū)別,但是有時候我填 127.0.0.1 就會告訴我跨域傳數(shù)據(jù)之類的,
                    // 總之很難……如果你部署到服務(wù)器的話,應(yīng)該是要改成服務(wù)器的地址的
                    fetch('http://localhost:8099/upload/speech', {
                        method: 'POST',
                        // 這里把 FormData 放到 body 傳過去;如果你還要傳別的數(shù)據(jù),都放到這個 FormData 里就可以傳過去
                        body: speechFormData
                    })
                    .then(response => {
                        console.log('response:', response);
                        if (response.status === 200) {
                            console.log('成功上傳音頻', response);
                        }
                    })
                    .then(data => console.log('data:', data))
                    .catch(error => console.error(error));

                    const imgFormData = new FormData();
                    imgFormData.append('img', imageBlob, filename+'.jpg');
                    fetch('http://localhost:8099/upload', {
                        method: 'POST',
                        body: imgFormData
                        })
                        .then(response => {
                            console.log('response:', response);
                            if (response.status === 200) {
                                console.log('上傳完成');
                            }
                            })
                        .then(data => console.log('data:', data))
                        .catch(error => console.error(error));
                }
            }
        };
    </script>
</body>
</html>

javascript 的部分

有兩個文件,放在 static 文件夾的 js 文件夾下:

user_camera.js

class SnapVideo {
    // 攝像頭流媒體
    stream;
    // 頁面dom
    videoElement = document.getElementById('videoElement');
    snapButton = document.getElementById('snapButton');
    photoElement = document.getElementById('photo');
    constructor() {
        const constraints = {
            audio: true,
            video: {
                facingMode: "environment",  // "user" 代表前置攝像頭
                width: 448,  // 視頻寬度
                height: 448,
                frameRate: 60,  // 每秒 60 幀
            }
        };
        // 綁定方法
        this.snapButton.onclick = () => this.takeSnapshot();
        // this.videoElement.width = constraints.video.width;
        // this.videoElement.height = constraints.video.height;
        // 獲取攝像頭流媒體
        this.getUserMedia(constraints, (stream) => {
            // 攝像頭流媒體成功回調(diào)
            this.stream = stream;
            this.videoElement.srcObject = stream;
        }, (e) => {
            // 攝像頭流媒體失敗回調(diào)
            if (e.message === 'Permission denied') {
                alert('您已經(jīng)禁止使用攝像頭');
            }
            console.log('navigator.getUserMedia error: ', e);
        })
    }
    getUserMedia(constrains, success, error) {
        if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
            //最新的標(biāo)準(zhǔn)API
            navigator.mediaDevices.getUserMedia(constrains).then(success).catch(error);
        } else if (navigator.webkitGetUserMedia) {
            //webkit核心瀏覽器
            navigator.webkitGetUserMedia(constraints, success, error)
        } else if (navigator.getUserMedia) {
            //舊版API
            navigator.getUserMedia(constraints, success, error);
        }
    }
    // 拍照
    takeSnapshot() {
        console.log('點擊了拍攝按鈕');
        // 利用 canvas 截取視頻圖片
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d');
        canvas.width = this.videoElement.videoWidth;
        canvas.height = this.videoElement.videoHeight;
        context.drawImage(this.videoElement, 0, 0, canvas.width, canvas.height);
        this.photoElement.src = canvas.toDataURL('image/png');
        canvas.toBlob(function (blob) {
        	// 把 blob 賦給 imageBlob;注意這個 imageBlob 是在 html 文件中聲明的??!
            imageBlob = new Blob([blob], {type: "image/png"});
        }, "image/png", 1);
        // this.photoElement.style.display = 'block';
    }
}

new SnapVideo();

另一個文件是 user_recorder.js文章來源地址http://www.zghlxwxcb.cn/news/detail-851941.html

// 錄音
const recordBtn = document.getElementById('recorderButton');

if (navigator.mediaDevices.getUserMedia) {
    let chunks = [];
    // 注意,這里這個 audio 傳參只能傳 true,傳別的,錄到的音頻就是損壞的??!
    const constraints = { audio: true };
    navigator.mediaDevices.getUserMedia(constraints).then(
        stream => {
            const mediaRecorder = new MediaRecorder(stream);
            recordBtn.onclick = () => {
                console.log("點擊");
                if (mediaRecorder.state === "recording") {
                    mediaRecorder.stop();
                    recordBtn.textContent = "錄音結(jié)束";
                } else {
                    mediaRecorder.start();
                    recordBtn.textContent = "錄音中...";
                }
            };
            mediaRecorder.ondataavailable = e => {
                chunks.push(e.data);
            };
            mediaRecorder.onstop = e => {
            	// 一樣的,把 blob 賦給 speechBlob,這個也是在 html 里面的 <script> 聲明的
                speechBlob = new Blob(chunks, {type: "audio/wav"});
                chunks = [];
            }
        },
        () => { console.error("授權(quán)失?。?); }
    );
} else {
    console.error("瀏覽器不支持 getUserMedia");
}

到了這里,關(guān)于flask 后端 + 微信小程序和網(wǎng)頁兩種前端:調(diào)用硬件(相機和錄音)和上傳至服務(wù)器的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 微信小程序商城搭建--后端+前端+小程序端

    微信小程序商城搭建--后端+前端+小程序端

    前端技術(shù):React、AntdesignPro、umi、JavaScript、ES6、TypeScript、 小程序 后端技術(shù):Springboot、Mybatis、Spring、Mysql 后端采用Springboot搭配前端React進行開發(fā),完成用戶管理、輪播圖管理、一級分類管理、商品管理、日志管理。 支持多圖上傳功能,封面圖。 采用JWT+攔截器進行接口攔截

    2024年02月05日
    瀏覽(29)
  • 微信小程序登錄+獲取手機號碼(前端+后端)

    微信小程序登錄+獲取手機號碼(前端+后端)

    上面這張是微信小程序官方原圖,登錄流程如上圖所示,下面一步步進行以及說一下碰到的坑。 1.wx.login()獲取code ? ? ? ? 調(diào)用微信小程序官方提供的方法獲取code提供給后端用以換取session_key、openid。 ? ? ? ? 注意:code只能使用一次就會失效,且有效期為5分鐘 2.后端收到

    2024年02月12日
    瀏覽(95)
  • 微信小程序登錄流程(包含前端、后端代碼)

    微信小程序登錄流程(包含前端、后端代碼)

    在微信小程序的開發(fā)過程中,如果想要保留 用戶 的 數(shù)據(jù) (比如: 操作記錄 、 購物車信息 等等)就必須要 用戶 登陸。為什么呢?比如說,數(shù)據(jù)庫中有一條 數(shù)據(jù) 你如何知道這條數(shù)據(jù)屬于誰?屬于那個用戶呢?這就需要用戶登錄來獲取 用戶 的 唯一標(biāo)識 從而確定這條數(shù)據(jù)是屬

    2024年02月03日
    瀏覽(100)
  • 在線選課的微信小程序(微信前端+網(wǎng)站后端)

    在線選課的微信小程序(微信前端+網(wǎng)站后端)

    目錄 一、前言 二、微信小程序端(老師、學(xué)生) 1.學(xué)生用戶前端小程序界面 ?2.老師前端小程序界面 三、后端(管理員、老師、學(xué)生) 3.老師后端 4.管理員后端 四、代碼獲取與調(diào)試 這是一個在線選課的微信小程序,使用了 idea + Navicat + maven + vue + 微信開發(fā)者工具 。 1.學(xué)生用

    2024年02月11日
    瀏覽(29)
  • 微信小程序獲取用戶手機號碼教程(前端+后端)

    微信小程序獲取用戶手機號碼教程(前端+后端)

    在開發(fā)一款微信小程序時,需要用戶進行微信登錄,獲取用戶的手機號碼來作為用戶的唯一標(biāo)識(userId),于是探索獲取用戶手機號碼的方式; (當(dāng)然,通過wx.login來獲取code,進而換取用戶的openid也是可以的) 目前版本的微信小程序獲取用戶手機號碼的方式如下: 前端開發(fā)

    2024年02月12日
    瀏覽(31)
  • 微信小程序獲取用戶手機號碼教程(前端+后端)

    微信小程序獲取用戶手機號碼教程(前端+后端)

    前些天發(fā)現(xiàn)了一個巨牛的人工智能學(xué)習(xí)網(wǎng)站,通俗易懂,風(fēng)趣幽默,忍不住分享一下給大家。點擊跳轉(zhuǎn)到網(wǎng)站,這篇文章男女通用,看懂了就去分享給你的碼吧。 在開發(fā)微信小程序時,獲取用戶手機號碼是常見的需求之一。本教程將為你詳細介紹如何在前端和后端實現(xiàn)獲取用

    2024年02月08日
    瀏覽(59)
  • 【微信小程序】前端+后端 :第一篇(基于javaweb 案例)

    【微信小程序】前端+后端 :第一篇(基于javaweb 案例)

    博主:??不許代碼碼上紅 歡迎:??點贊、收藏、關(guān)注、評論。 點擊新建項目 這里記得選擇web application 點擊下一步 這是我們需要的目錄結(jié)構(gòu) 如果沒有如下圖這個東西 可以點擊+號 選擇Artifact 即可 4.1、創(chuàng)建一個新的頁面pages 目錄結(jié)構(gòu) 4.2、demo2.js 4.3、demo2.wxml 微信小程序端

    2024年02月09日
    瀏覽(24)
  • 前端將后端數(shù)據(jù)流轉(zhuǎn)為圖片(微信小程序)

    獲取后端流的請求responseType必須使用arraybuffer 將后端數(shù)據(jù)劉轉(zhuǎn)換為base64再轉(zhuǎn)換為本地圖片 html與data

    2024年02月15日
    瀏覽(24)
  • 前端uni微信小程序和后端nodejs使用websoket

    需求 前端向后臺服務(wù)器發(fā)請求獲取驗證碼,然后端游輸入驗證碼,向我的后端發(fā)請求獲取驗證信息。后臺給游戲端返回信息的時候同時給微信小程序端返回驗證結(jié)果。意思是不要微信小程序端主動觸發(fā),驗證是否綁定的請求。 思路 后端生成驗證碼時存入用戶的唯一Id和ip,前

    2024年02月03日
    瀏覽(23)
  • 以php為后端,vue為前端的租房微信小程序

    租房微信小程序是一個非常有用的應(yīng)用,它不僅可以幫助人們快速找到心儀的房屋,還可以提供便捷的房屋租賃服務(wù)。本文將介紹如何使用PHP作為后端語言和Vue作為前端框架來開發(fā)一個租房微信小程序。 環(huán)境搭建 首先,需要在本地或云上安裝并配置PHP和Vue環(huán)境。可以使用X

    2024年02月08日
    瀏覽(24)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包