Parcourir la source

feature:优化壁纸的传输数据的方法

zeng.chen il y a 7 mois
Parent
commit
fa29c9bf24

+ 3 - 4
devices/ble_manager.js

@@ -473,13 +473,13 @@ class bleManager {
   }
 
   // 发送数据到指定设备
-  async sendData(data, callback) {
+  async sendData(data, callback, needChange) {
     var that = this
     return new Promise((resolve, reject) => {
       var buffer = null;
       // todo 判断是否是buffer
-      // if (Buffer.isBuffer(data)) {
-      //     buffer = data;
+      // if (needChange) {
+      //   buffer = data;
       // } else {
       buffer = new ArrayBuffer(data.length);
       // 下面是赋值,不能删
@@ -496,7 +496,6 @@ class bleManager {
         characteristicId: that.publicDevice.characteristicId,
         value: buffer,
         success: (res) => {
-          // console.log('数据发送成功:');
           if (callback) {
             callback(true)
           }

+ 32 - 2
devices/bluetooth/bt_cmd.js

@@ -245,8 +245,8 @@ class BtCmd {
     }
     // 壁纸指令 
     static wallPaperData(value) {
-        let cmd = this._build(CmdBase.wallPaperData, value);
-        // console.log("发送图片数据:", value)
+        let uint8Array = new Uint8Array(value);
+        let cmd = this._build(CmdBase.wallPaperData, uint8Array);
         return cmd;
     }
     // 背景图指令 1开始, 0结束
@@ -274,7 +274,37 @@ class BtCmd {
         return this._build(0x36, [0x00]);
     }
 
+    static _buildOther(data) {
+        const cmd = [];
+
+        // 固定头部
+        cmd.push(...this._header);
 
+        // 版本号
+        cmd.push(this._version);
+
+        // 命令类型
+        cmd.push(cmdType);
+
+        if (isWriteChildCmdLength) {
+            // 子命令长度
+            const childLength = this._int2Hex(otherCmd.length);
+            cmd.push(childLength);
+        }
+
+        // 其他命令
+        if (otherCmd.length > 0) {
+            for (const element of otherCmd) {
+                cmd.push(this._int2Hex(element));
+            }
+        }
+
+        // 命令长度(位置在版本号之后)
+        const length = cmd.length + 1;
+        const l = this._int2Hex(length);
+        cmd.splice(5, 0, l);
+        return cmd;
+    }
     // 生成命令(固定头部+版本号+命令总长度+命令类型+)
     static _build(cmdType, otherCmd = [], isWriteChildCmdLength = true) {
         const cmd = [];

+ 2 - 0
devices/bluetooth/bt_parse.js

@@ -175,6 +175,8 @@ class BtParse {
         switch (type) {
             // 校验设备
             case CmdBase.checkDeviceSuccess:
+            case CmdBase.checkDevice:
+                // [84, 68, 68, 72, 1, 17, 40, 9, 115, 109, 97, 114, 116, 95, 65, 50, 70]
                 break;
 
             // 按键   短按、长按等

+ 22 - 22
devices/bt_helper.js

@@ -141,18 +141,18 @@ class BtHelper {
         mDevice.volume = volume;
         break;
 
-        ///电量
+      ///电量
       case EnumCmdEvent.battery:
         mDevice.kwh = event.kwh;
         break;
 
-        ///低时延模式  低时延模式开启 1:音乐 , 2: 游戏 , 3: movie
+      ///低时延模式  低时延模式开启 1:音乐 , 2: 游戏 , 3: movie
       case EnumCmdEvent.lowDelayMode:
         mDevice.lowDelayMode = event.lowDelayMode;
         mDevice.lowDelayModeOpen = event.lowDelayModeOpen;
         break;
 
-        ///电量 耳机电量
+      ///电量 耳机电量
       case EnumCmdEvent.batteryEarphone:
         mDevice.kwh = event.kwh;
         mDevice.kwhLeft = event.kwhLeft;
@@ -160,12 +160,12 @@ class BtHelper {
         mDevice.kwhBox = event.kwhBox;
         break;
 
-        ///是否支持TTS
+      ///是否支持TTS
       case EnumCmdEvent.enableTTS:
         mDevice.enableTTS = event.enableTTS;
         break;
 
-        ///切换设备连接模式 0:未知 1:低功耗蓝牙 2:wifi类型 3:经典蓝牙(不做任何操作) 4:4G类型
+      ///切换设备连接模式 0:未知 1:低功耗蓝牙 2:wifi类型 3:经典蓝牙(不做任何操作) 4:4G类型
       case EnumCmdEvent.switchDeviceMode:
         var deviceMode = event.deviceMode.index;
         if (deviceMode != null) {
@@ -174,14 +174,14 @@ class BtHelper {
         }
         break;
 
-        ///4G外插卡  4G虚拟卡 当前使用的sim卡
+      ///4G外插卡  4G虚拟卡 当前使用的sim卡
       case EnumCmdEvent.sim:
         mDevice.sim = event.sim;
         mDevice.eSim = event.eSim;
         mDevice.simIndex = event.simIndex;
         break;
 
-        ///闹钟是否开启  闹钟周期 闹钟唤醒时间
+      ///闹钟是否开启  闹钟周期 闹钟唤醒时间
       case EnumCmdEvent.wake:
         mDevice.wakeSwitch = event.wakeSwitch;
         mDevice.wakeCycle = event.wakeCycle;
@@ -189,14 +189,14 @@ class BtHelper {
         mDevice.wakeMinutes = event.wakeMinutes;
         break;
 
-        ///休眠是否开启 休眠时间
+      ///休眠是否开启 休眠时间
       case EnumCmdEvent.sleep:
         mDevice.sleepSwitch = event.sleepSwitch;
         mDevice.sleepHour = event.sleepHour;
         mDevice.sleepMinutes = event.sleepMinutes;
         break;
 
-        ///版本和型号
+      ///版本和型号
       case EnumCmdEvent.version:
         mDevice.version = event.version;
         var clientType = mDevice.clientType ?? "";
@@ -229,7 +229,7 @@ class BtHelper {
         // }
         break;
 
-        ///云小微授权
+      ///云小微授权
       case EnumCmdEvent.auth:
         var authInfo = event.authInfo;
         mDevice.authInfo = authInfo;
@@ -245,17 +245,17 @@ class BtHelper {
         // });
         break;
 
-        ///EQ音效
+      ///EQ音效
       case EnumCmdEvent.eq:
         mDevice.eqs = event.eqs;
         break;
 
-        ///payId 充流量使用
+      ///payId 充流量使用
       case EnumCmdEvent.payId:
         mDevice.payId = event.payId;
         break;
 
-        ///QQ音乐使用dsn授权
+      ///QQ音乐使用dsn授权
       case EnumCmdEvent.dsn:
         var dsn = event.dsn;
         mDevice.dsn = dsn;
@@ -264,13 +264,13 @@ class BtHelper {
         // ProviderUtil.twelvePublic.wifiDeviceConnected();
         break;
 
-        ///自动切换 0,1不能
-        ///
+      ///自动切换 0,1不能
+      ///
       case EnumCmdEvent.netModeAuto:
         mDevice.netModeAuto = event.netModeAuto;
         break;
 
-        ///解绑设备
+      ///解绑设备
       case EnumCmdEvent.unbind:
         //   let unbindAddress = event.item.address ?? "";
         //     if (unbindAddress != mDevice.address) {
@@ -286,7 +286,7 @@ class BtHelper {
 
         break;
 
-        ///解绑设备
+      ///解绑设备
       case EnumCmdEvent.ctrlStatus:
         // List < int > ctrlList = event.ctrlStatus;
         // if (ctrlList.length == 3) {
@@ -308,7 +308,7 @@ class BtHelper {
         // notifyListeners();
         break;
 
-        ///设备信息
+      ///设备信息
       case EnumCmdEvent.getDeviceInfo:
         //   List list = [];
         //   String userId = ProviderUtil.user.userModel.uid ?? "";
@@ -744,9 +744,9 @@ class BtHelper {
     that.send(BtCmd.wallPaper(value));
   }
   // 壁纸指令 
-  wallPaperData(value, callback) {
-    // this.send(BtCmd.wallPaperData(value));
-    BtHelper.sendCallBack(BtCmd.wallPaperData(value), callback);
+  wallPaperData(value) {
+    this.send(BtCmd.wallPaperData(value));
+    // BtHelper.sendCallBack(BtCmd.wallPaperData(value));
   }
 
   // 壁纸指令 
@@ -771,7 +771,7 @@ class BtHelper {
     this.send(BtCmd.otaCmd(value));
   }
   otaData(value, callback) {
-    BtHelper.sendCallBack(BtCmd.wallPaperData(value), callback);
+    BtHelper.sendCallBack(BtCmd.otaData(value), callback);
   }
 
   async closeBle() {

+ 130 - 157
pages/piano/cropper/cropper.js

@@ -13,11 +13,11 @@ Page({
    */
   data: {
     src: "",
-    width: 300,//宽度
-    height: 300,//高度
+    width: 320,//宽度
+    height: 320,//高度
 
-    max_width: 300,
-    max_height: 300,
+    max_width: 320,
+    max_height: 320,
     disable_rotate: true, //是否禁用旋转
     disable_ratio: true, //锁定比例
     limit_move: true, //是否限制移动
@@ -27,41 +27,36 @@ Page({
   },
   cropper: null,
 
-
-  // 将 RGBA 数据转换为 RGB565 格式
-  RGBAtoRGB565(data) {
-    const rgb565Array = new Uint16Array(data.length / 4);
-
-    for (let i = 0; i < data.length; i += 4) {
-      const r = data[i];
-      const g = data[i + 1];
-      const b = data[i + 2];
-      // 转换为 RGB565
-      const rgb565 = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-      rgb565Array[i / 4] = rgb565;
+  // 图片转RGB565
+  convertToRGB565(imageData) {
+    const { data, width, height } = imageData;
+    // 原始像素数据 (RGBA 格式)
+    const rgba = new Uint8Array(data);
+
+    // 创建 RGB565 的 ArrayBuffer
+    const pixelCount = width * height;
+    const rgb565Buffer = new ArrayBuffer(pixelCount * 2); // 每像素 2 字节
+    const rgb565View = new Uint16Array(rgb565Buffer);
+
+    // 转换每个像素
+    for (let i = 0; i < pixelCount; i++) {
+      const r = rgba[i * 4];     // Red
+      const g = rgba[i * 4 + 1]; // Green
+      const b = rgba[i * 4 + 2]; // Blue
+
+      // RGB565 的位运算
+      const r5 = (r >> 3) & 0x1F; // R 的高 5 位
+      const g6 = (g >> 2) & 0x3F; // G 的高 6 位
+      const b5 = (b >> 3) & 0x1F; // B 的高 5 位
+
+      // 组合成 RGB565 格式
+      const rgb565 = (r5 << 11) | (g6 << 5) | b5;
+
+      // 写入到 RGB565 的 buffer 中
+      rgb565View[i] = rgb565;
     }
 
-    return rgb565Array;
-  },
-
-  // 保存为 .bin 文件
-  saveAsBinFile(data, width, height) {
-    const arrayBuffer = data.buffer;
-
-    wx.getFileSystemManager().writeFile({
-      filePath: `${wx.env.USER_DATA_PATH}/image_rgb565_${width}x${height}.bin`,
-      data: arrayBuffer,
-      encoding: 'binary',
-      success: () => {
-        wx.showToast({
-          title: '保存成功',
-          icon: 'success',
-        });
-      },
-      fail: (err) => {
-        console.error('文件保存失败:', err);
-      },
-    });
+    return rgb565Buffer;
   },
   cropperload(e) {
     console.log('cropper加载完成');
@@ -108,58 +103,82 @@ Page({
     wx.showLoading({
       title: '图片裁剪中',
     })
+    const fs = wx.getFileSystemManager();
+
     this.cropper.getImg((obj) => {
       // app.globalData.imgSrc = obj.url;
       console.log("裁剪图片:", obj);
-      _this.readLocalFileAndConvertToBase64(obj.url);
-      // _this.readBinFile("../../pagesA/images/th01.bin");
+      fs.readFile({
+        filePath: obj.url,
+        encoding: '', // 不指定编码以获取原始二进制数据
+        success: (res) => {
+          console.log("下载文件成功:", res)
+          let rgbData = _this.convertToRGB565({
+            width: obj.width,
+            height: obj.height,
+            data: res.data
+          })
+          _this.data._imageBuffer = rgbData;
+          console.log("下载文件成功2:", _this.data._imageBuffer)
+          wx.hideLoading();
+          wx.showLoading({
+            title: '开始传输图片',
+          })
+          _this.startImage();
+        },
+        fail: (err) => {
+          console.error('读取 .bin 文件失败:', err);
+        },
+      });
     });
+    // 651kb的
+    // _this.downloadAndSaveFile("https://music-play.oss-cn-shenzhen.aliyuncs.com/backOss/file/6a909799a6924e6f86a4683e6da4fad4.bin");
+    // 55kb的
+    // _this.downloadAndSaveFile("https://music-play.oss-cn-shenzhen.aliyuncs.com/backOss/file/55d2dd22bd554eb19b71536bec4ba42c.bin");
+
   },
-  submitTest() {
-    route_util.jump("../../pagesA/index/index")
-  },
-  // 读取本地文件并转换为 Base64 字符串
-  readLocalFileAndConvertToBase64(filePath) {
+  // 下载网络文件并保存到本地
+  downloadAndSaveFile(url) {
+    // https://music-play.oss-cn-shenzhen.aliyuncs.com/backOss/file/6a909799a6924e6f86a4683e6da4fad4.bin
     const fs = wx.getFileSystemManager();
     let _this = this;
-    fs.readFile({
-      filePath: filePath,
-      encoding: 'base64',
+    wx.downloadFile({
+      url: url, // 网络文件的 URL
       success: (res) => {
-        // const base64Data = 'data:image/png;base64,' + res.data;
-        // let rgbData = _this.RGBAtoRGB565(res.data)
-        let rgbData = res.data
-        console.log("转换rgb:", rgbData.length)
-        _this.data._imageBuffer = rgbData;
-        wx.hideLoading();
-        wx.showLoading({
-          title: '开始传输图片',
-        })
-        _this.startImage();
-      },
-      fail: (err) => {
-        console.error('读取文件失败:', err);
-      }
-    });
-  },
-  readBinFile(filePath) {
-    const fs = wx.getFileSystemManager();
-
-    fs.readFile({
-      filePath: filePath,
-      encoding: '', // 不指定编码以获取原始二进制数据
-      success: (res) => {
-        console.log("读取 .bin 文件成功:", res.data);
-        // 处理读取到的二进制数据
-        this.processBinData(res.data);
+        if (res.statusCode === 200) {
+          // 下载成功,res.tempFilePath 是临时文件路径
+          const tempFilePath = res.tempFilePath;
+          console.log("下载文件:", res)
+          fs.readFile({
+            filePath: tempFilePath,
+            // encoding: '', // 不指定编码以获取原始二进制数据
+            success: (res) => {
+              console.log("下载文件成功:", res.data)
+              let rgbData = res.data
+              _this.data._imageBuffer = rgbData;
+              // console.log("下载文件成功2:", _this.data._imageBuffer)
+
+              wx.hideLoading();
+              wx.showLoading({
+                title: '开始传输图片',
+              })
+              _this.startImage();
+            },
+            fail: (err) => {
+              console.error('读取 .bin 文件失败:', err);
+            },
+          });
+        } else {
+          console.error('下载文件失败:', res.statusCode);
+        }
       },
       fail: (err) => {
-        console.error('读取 .bin 文件失败:', err);
+        console.error('下载文件失败:', err);
       },
     });
   },
   checkAndRequestImagePermission: function () {
-    const self = this;
+    const _this = this;
 
     // 检查用户是否已经授权访问相册
     wx.getSetting({
@@ -205,98 +224,55 @@ Page({
         }
       }
     });
-
-    // 检查用户是否已经授权使用相机
-    wx.getSetting({
-      success(res) {
-        if (!res.authSetting['scope.camera']) {
-          // 用户未授权使用相机,请求用户授权
-          wx.authorize({
-            scope: 'scope.camera',
-            success() {
-              // 用户同意授权
-              console.log('用户已授权使用相机');
-              // 可以在这里执行使用相机的操作
-            },
-            fail() {
-              // 用户拒绝授权
-              console.log('用户拒绝授权使用相机');
-              wx.showModal({
-                title: '提示',
-                content: '您拒绝了使用相机的权限,请在设置中手动开启',
-                showCancel: false,
-                success(res) {
-                  if (res.confirm) {
-                    // 跳转到设置页面
-                    wx.openSetting({
-                      success(settingRes) {
-                        if (settingRes.authSetting['scope.camera']) {
-                          console.log('用户已在设置中开启使用相机的权限');
-                          // 可以在这里执行使用相机的操作
-                        } else {
-                          console.log('用户仍未授权使用相机');
-                        }
-                      }
-                    });
-                  }
-                }
-              });
-            }
-          });
-        } else {
-          // 用户已授权使用相机
-          console.log('用户已授权使用相机');
-          // 可以在这里执行使用相机的操作
-        }
+  },
+  async startImage() {
+    BtHelper.sendCallBack(BtCmd.wallPaper(1), function (res) {
+      if (!res) {
+        wx.hideLoading()
+        wx.showToast({
+          title: '发送失败',
+          icon: 'none'
+        })
       }
     });
   },
-  startImage() {
-    BtHelper.getInstance().send(BtCmd.wallPaper(1));
-  },
   sliceDataIntoChunks(data, chunkSize) {
+    console.log("发送图片数据:", data.byteLength)
     const chunks = [];
-    for (let i = 0; i < data.length; i += chunkSize) {
+    // for (let i = 0; i < data.length; i += chunkSize) {
+    for (let i = 0; i < data.byteLength; i += chunkSize) {
       const chunk = data.slice(i, i + chunkSize);
       chunks.push(chunk);
     }
     return chunks;
   },
-  startSendImage(imageBuffer) {
-    if (imageBuffer == null) {
-      wx.showToast({
-        title: '图片裁剪失败',
-        icon: 'none'
-      })
-      _this.endImage(2)
-      return;
-    }
-    // _this.sendImage(imageBuffer, 0)
-
-    // }
-  },
   async sendImage(imageBuffer, index) {
     let _this = this
 
-    // if (index >= chunkSize) {
-    //   wx.showModal({
-    //     title: '图片上传成功1',
-    //     showCancel: false
-    //   })
-    //   _this.endImage(0)
-    //   return;
-    // }
-
-    let chunks = this.sliceDataIntoChunks(imageBuffer, 20);
+    wx.hideLoading()
+    console.log("发送图片数据0:", index, imageBuffer.byteLength)
+    // console.log("发送图片数据0:", index, imageBuffer.length)
+    let chunks = this.sliceDataIntoChunks(imageBuffer, 16);
 
     let next = 0;
-    let total = imageBuffer.length;
+    let total = imageBuffer.byteLength;
+    // let total = imageBuffer.length;
+    let btHelper = BtHelper.getInstance();
     for (let i = 0; i < chunks.length; i++) {
       const chunk = chunks[i];
-      next += chunk.length;
-      console.log("发送图片数据:", i, next, chunk)
+      next += chunk.byteLength;
+      // next += chunk.length;
+      let uint8Array = new Uint8Array(chunk);
+      let unit16 = uint8Array.map(item => {
+        return item.toString(16)
+      });
+      console.log("发送图片数据1:", i, next, total, unit16)
+      _this.updateProgress(next, total);
+
+      await _this.delay(20);
+      let res = await btHelper.wallPaperSyncData(chunk);
+      // btHelper.wallPaperData(chunk);
 
-      let res = await BtHelper.getInstance().wallPaperSyncData(chunk);
       let nowDate = Date.now()
       if (i === chunks.length - 1 && res) {
         wx.showModal({
@@ -304,17 +280,18 @@ Page({
           showCancel: false
         })
         _this.endImage(0)
+
       } else if (!res) {
         wx.showModal({
-          title: '图片上传失败',
+          title: '图片上传失败',
           showCancel: false
         })
         _this.endImage(2)
-        break;
       }
-      _this.updateProgress(next, total);
     }
-
+  },
+  async delay(ms) {
+    return new Promise(resolve => setTimeout(resolve, ms));
   },
   endImage(value) {
     BtHelper.getInstance().wallPaper(value);
@@ -337,8 +314,6 @@ Page({
       wx.showToast({
         title: '图片上传成功',
       })
-      _this.endImage(0)
-
     } else {
       _this.setData({
         progress: progress,
@@ -349,8 +324,6 @@ Page({
    * 生命周期函数--监听页面加载
    */
   onLoad(options) {
-    console.log(options.param)
-    // let json = JSON.parse(options.param)
     this.checkAndRequestImagePermission()
     this.cropper = this.selectComponent("#image-cropper");
     this.cropper.imgReset();