Przeglądaj źródła

feature:修改黑胶壁纸上传jpg图片

zeng.chen 7 miesięcy temu
rodzic
commit
67b26a7eb9

+ 10 - 9
devices/ble_manager.js

@@ -101,7 +101,7 @@ class bleManager {
               temp.mac = temp.advertisData ? that.buf2hex(temp.advertisData) : '';
               temp.mac2 = that.ab2hex(temp.advertisData ?? "")
               // if (that.callBackConnect != null) {
-              // console.log("2222:", temp.mac, temp.mac2);
+              console.log("2222:", temp.mac, ":", temp.mac2, ":", temp.deviceId, temp);
               if (that.callBackConnect != null) {
                 that.callBackConnect(temp);
               }
@@ -110,21 +110,22 @@ class bleManager {
           }
         } else {
           for (var i = 0; i < res.devices.length; i++) {
-            if (that.compareList.length > 0) {
-              var has = false;
-              for (var j = 0; j < that.compareList.length; j++) {
-                if (res.devices[i].name != "") {
+            if (res.devices[i].name != "") {
+
+              if (that.compareList.length > 0) {
+                var has = false;
+                for (var j = 0; j < that.compareList.length; j++) {
                   if (res.devices[i].deviceId == that.compareList[j].deviceId) {
                     has = true;
                     break;
                   }
                 }
-              }
-              if (!has) {
+                if (!has) {
+                  that.compareList.push(res.devices[i]);
+                }
+              } else {
                 that.compareList.push(res.devices[i]);
               }
-            } else {
-              that.compareList.push(res.devices[i]);
             }
           }
         }

+ 10 - 4
devices/bluetooth/bt_cmd.js

@@ -241,7 +241,9 @@ class BtCmd {
     /* 黑胶音箱的指令 */
     // 壁纸指令 1开始, 0结束
     static wallPaper(value) {
-        return this._build(CmdBase.wallPaper, [value]);
+        let cmd = this._build(CmdBase.wallPaper, [value]);
+        console.log("结束图片上传:", cmd);
+        return cmd;
     }
     // 壁纸指令 
     static wallPaperData(value) {
@@ -306,7 +308,7 @@ class BtCmd {
         return cmd;
     }
     // 生成命令(固定头部+版本号+命令总长度+命令类型+)
-    static _build(cmdType, otherCmd = [], isWriteChildCmdLength = true) {
+    static _build(cmdType, otherCmd = [], isWriteChildCmdLength = true, isChangeOther = true) {
         const cmd = [];
 
         // 固定头部
@@ -326,8 +328,12 @@ class BtCmd {
 
         // 其他命令
         if (otherCmd.length > 0) {
-            for (const element of otherCmd) {
-                cmd.push(this._int2Hex(element));
+            if (isChangeOther) {
+                for (const element of otherCmd) {
+                    cmd.push(this._int2Hex(element));
+                }
+            } else {
+                cmd.concat(otherCmd);
             }
         }
 

+ 1 - 1
devices/bt_helper.js

@@ -738,7 +738,7 @@ class BtHelper {
   }
 
   /* 黑胶音箱的指令 */
-  // 壁纸指令 1开始, 0结束
+  // 壁纸指令 1开始, 0结束, 2异常
   wallPaper(value) {
     var that = this;
     that.send(BtCmd.wallPaper(value));

+ 1 - 1
pages/components/image-cropper/image-cropper.js

@@ -308,7 +308,7 @@ Component({
                     height: Math.round(this.data.height * this.data.export_scale),
                     destWidth: this.data.width * this.data.export_scale,
                     destHeight: Math.round(this.data.height) * this.data.export_scale,
-                    fileType: 'png',
+                    fileType: 'jpg',
                     quality: this.data.quality,
                     canvasId: this.data.el,
                     success: (res) => {

+ 213 - 97
pages/piano/cropper/cropper.js

@@ -31,7 +31,7 @@ Page({
     let that = this
     if (this.data._chunks.length > 0) {
       wx.showModal({
-        title: '保存图片中,确定要中断退出吗?',
+        title: '保存壁纸中,确定要中断退出吗?',
         content: '',
         complete: (res) => {
           if (res.confirm) {
@@ -48,36 +48,87 @@ Page({
       })
     }
   },
-  // 图片转RGB565
-  convertToRGB565(imageData) {
-    const { data, width, height } = imageData;
-    // 原始像素数据 (RGBA 格式)
-    const rgba = new Uint8Array(data);
+  convertImageDataToRGB565(imageData, width, height) {
+    // 创建一个 Uint16Array 来存储 RGB565 数据
+    const rgb565Data = new Uint16Array(width * height);
+
+    // 将 RGBA 数据转换为 RGB565 数据
+    for (let i = 0; i < imageData.length; i += 4) {
+      const r = imageData[i];
+      const g = imageData[i + 1];
+      const b = imageData[i + 2];
+      // const a = imageData[i + 3]; // 透明度,如果需要可以使用
+
+      // 将 RGB 转换为 RGB565
+      const rgb565 = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
+      rgb565Data[i / 4] = rgb565;
+    }
+    return rgb565Data
+
+  },
+
+  generateLVGLBinFile(rgb565Data, width, height) {
+    const header = new ArrayBuffer(32);
+    const headerView = new DataView(header);
+    // 十六进制字符串
+    // const hexString = "04 80 07 3c ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff";
+    const hexString = "04 80 07 3c";
+
+    // 将十六进制字符串转换为字节数组
+    const bytes = hexString.split(' ').map(byte => parseInt(byte, 10));
+    console.log(bytes);
+    // 将字节数组写入 headerView
+    bytes.forEach((byte, index) => {
+      headerView[index] = byte
+    });
 
-    // 创建 RGB565 的 ArrayBuffer
+
+    // 创建文件数据
+    const fileData = new Uint8Array(header.byteLength + rgb565Data.byteLength);
+    console.log("fileData:", fileData.length, fileData.byteLength);
+    fileData.set(new Uint8Array(header), 0); // 添加头部信息
+    fileData.set(new Uint8Array(rgb565Data.buffer), header.byteLength); // 添加 RGB565 数据
+    return fileData;
+  },
+  // 转换 RGBA 数据为 RGB565
+  imageDataToRGB565(rgbaData, width, height) {
     const pixelCount = width * height;
-    const rgb565Buffer = new ArrayBuffer(pixelCount * 2); // 每像素 2 字节
-    const rgb565View = new Uint16Array(rgb565Buffer);
+    // 十六进制字符串
+    // const hexString = "04 80 07 3c ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff";
+    const hexString = "04 80 07 3c";
 
-    // 转换每个像素
-    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 位
+    // 将十六进制字符串转换为字节数组
+    const bytes = hexString.split(' ').map(byte => parseInt(byte, 10));
+    console.log(bytes);
+
+    const outputData = new Uint8Array(pixelCount * 2 + bytes.length); // 文件头 + 每像素 4 字节 (RGB888 + Alpha)
 
-      // 组合成 RGB565 格式
+    // 将字节数组写入 headerView
+    bytes.forEach((byte, index) => {
+      outputData[index] = byte
+    });
+
+    // 写入像素数据
+    let offset = bytes.length;
+    for (let i = 0; i < pixelCount; i++) {
+      const r = rgbaData[i * 4];
+      const g = rgbaData[i * 4 + 1];
+      const b = rgbaData[i * 4 + 2];
+
+      // 转换为 RGB565 格式
+      const r5 = (r >> 3) & 0x1F;
+      const g6 = (g >> 2) & 0x3F;
+      const b5 = (b >> 3) & 0x1F;
       const rgb565 = (r5 << 11) | (g6 << 5) | b5;
 
-      // 写入到 RGB565 的 buffer 中
-      rgb565View[i] = rgb565;
+      // 写入 RGB565 (小端序)
+      outputData[offset++] = rgb565 & 0xFF; // 低字节
+      outputData[offset++] = (rgb565 >> 8) & 0xFF; // 高字节
     }
 
-    return rgb565Buffer;
+    console.log('最终偏移:', offset)
+    return outputData;
   },
   cropperload(e) {
     console.log('cropper加载完成');
@@ -93,22 +144,56 @@ Page({
           title: '加载中',
         })
         const tempFilePaths = res.tempFiles[0].tempFilePath;
-        //重置图片角度、缩放、位置
+        // //重置壁纸角度、缩放、位置
         that.cropper.imgReset();
         that.setData({
           src: tempFilePaths
         });
+        // that.testUpload(tempFilePaths)
+      }, fail(res) {
+        console.log(res)
       }
     })
   },
+  testUpload(url) {
+    const fs = wx.getFileSystemManager();
+    wx.showLoading({
+      title: '壁纸裁剪中',
+    })
+    let _this = this
+    // app.globalData.imgSrc = obj.url;
+    console.log("裁剪壁纸:", url);
+    _this.data._imgUrl = url
+    fs.readFile({
+      filePath: url,
+      encoding: '', // 不指定编码以获取原始二进制数据
+      success: (obj) => {
+        console.log("加载文件成功:", obj.data.byteLength, obj.data.length)
+
+        let binData = obj.data;
+        _this.sliceDataIntoChunks(binData, 64);
+
+        console.log("加载文件成功2:", binData.byteLength, binData.length)
+        _this.data._imageBufferLength = binData.byteLength ?? binData.length
+        wx.hideLoading();
+        wx.showLoading({
+          title: '开始传输壁纸',
+        })
+        _this.startImage()
+      },
+      fail: (err) => {
+        console.error('读取 .bin 文件失败:', err);
+      },
+    });
+  },
   loadimage(e) {
     wx.hideLoading();
-    console.log('图片', e);
+    console.log('壁纸', e);
     this.cropper.imgReset();
   },
   clickcut(e) {
     console.log("clickcut:", e.detail);
-    //图片预览
+    //壁纸预览
     wx.previewImage({
       current: e.detail.url,
       urls: [e.detail.url]
@@ -121,34 +206,62 @@ Page({
   },
   submit() {
     let _this = this
-    wx.showLoading({
-      title: '图片裁剪中',
-    })
+
+    // this.cropper.getImgData((obj) => {
+
+    //   _this.cropper.getImg((obj2) => {
+    //     // app.globalData.imgSrc = obj.url;
+    //     console.log("裁剪壁纸:", obj2);
+    //     _this.data._imgUrl = obj2.url
+    //   });
+
+    //   wx.showLoading({
+    //     title: '壁纸裁剪中',
+    //   })
+
+    //   // let binData = _this.imageDataToRGB565(obj.data, obj.width, obj.height)
+
+    //   // const rgb565Data = _this.convertImageDataToRGB565(obj.data, obj.width, obj.height)
+    //   // // 生成 LVGL 二进制文件
+    //   // const binData = _this.generateLVGLBinFile(rgb565Data, obj.width, obj.height);
+
+    //   const binData = _this.imageDataToRGB565(obj.data, obj.width, obj.height);
+
+    //   _this.sliceDataIntoChunks(binData, 128);
+
+    //   console.log("下载文件成功2:", binData.byteLength, binData.length)
+    //   _this.data._imageBufferLength = binData.byteLength ?? binData.length
+    //   wx.hideLoading();
+    //   wx.showLoading({
+    //     title: '开始传输壁纸',
+    //   })
+    //   _this.startImage();
+    // });
+
     const fs = wx.getFileSystemManager();
     this.cropper.getImg((obj) => {
+      wx.showLoading({
+        title: '壁纸裁剪中',
+      })
       // app.globalData.imgSrc = obj.url;
-      console.log("裁剪图片:", obj);
+      console.log("裁剪壁纸:", obj);
       _this.data._imgUrl = obj.url
       fs.readFile({
         filePath: obj.url,
         encoding: '', // 不指定编码以获取原始二进制数据
-        success: (res) => {
-          console.log("下载文件成功:", res)
-          let rgbData = _this.convertToRGB565({
-            width: obj.width,
-            height: obj.height,
-            data: res.data
-          })
-          console.log("下载文件成功2:", rgbData.byteLength)
-          _this.data._imageBufferLength = rgbData.byteLength
+        success: (obj) => {
+          console.log("加载文件成功:", obj.data.byteLength, obj.data.length)
+
+          let binData = obj.data;
+          _this.sliceDataIntoChunks(binData, 64);
+
+          console.log("加载文件成功2:", binData.byteLength, binData.length)
+          _this.data._imageBufferLength = binData.byteLength ?? binData.length
           wx.hideLoading();
           wx.showLoading({
-            title: '开始传输图片',
+            title: '开始传输壁纸',
           })
-          _this.startImage(rgbData);
-          // 测试
-          // _this.sendImage()
-          // _this.startProgress()
+          _this.startImage()
         },
         fail: (err) => {
           console.error('读取 .bin 文件失败:', err);
@@ -156,10 +269,7 @@ Page({
       });
     });
     // 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");
-    // _this.downloadAndSaveFile("https://music-play.oss-cn-shenzhen.aliyuncs.com/backOss/file/7498f0c94c5646d0a4648f313a2fa05c.bin");
+    // _this.downloadAndSaveFile("https://music-play.oss-cn-shenzhen.aliyuncs.com/backOss/file/8770a6097d9940b59032d099b2fdde3b.bin");
 
   },
   // 下载网络文件并保存到本地
@@ -179,10 +289,11 @@ Page({
             success: (res) => {
               console.log("下载文件成功:", res.data)
               let rgbData = res.data
+              _this.data._imageBufferLength = rgbData.byteLength
 
               wx.hideLoading();
               wx.showLoading({
-                title: '开始传输图片',
+                title: '开始传输壁纸',
               })
               _this.startImage(rgbData);
             },
@@ -211,7 +322,8 @@ Page({
             scope: 'scope.writePhotosAlbum',
             success() {
               // 用户同意授权
-              console.log('用户已授权访问相册');
+              console.log('用户已授权访问相册1');
+              _this.upload()
               // 可以在这里执行访问相册的操作
             },
             fail() {
@@ -219,7 +331,7 @@ Page({
               console.log('用户拒绝授权访问相册');
               wx.showModal({
                 title: '提示',
-                content: '您拒绝了访问相册的权限,无法上传图片',
+                content: '您拒绝了访问相册的权限,无法上传壁纸',
                 showCancel: false,
                 success(res) {
                   if (res.confirm) {
@@ -229,7 +341,7 @@ Page({
                         if (settingRes.authSetting['scope.writePhotosAlbum']) {
                           console.log('用户已在设置中开启访问相册的权限');
                           // 可以在这里执行访问相册的操作
-                          _this.upload(); //上传图片
+                          _this.upload(); //上传壁纸
                         } else {
                           console.log('用户仍未授权访问相册');
                         }
@@ -242,14 +354,13 @@ Page({
           });
         } else {
           // 用户已授权访问相册
-          console.log('用户已授权访问相册');
+          console.log('用户已授权访问相册2');
           // 可以在这里执行访问相册的操作
         }
       }
     });
   },
-  async startImage(imageBuffer) {
-    this.sliceDataIntoChunks(imageBuffer, 128);
+  async startImage() {
 
     BtHelper.sendCallBack(BtCmd.wallPaper(1), function (res) {
       if (!res) {
@@ -262,13 +373,20 @@ Page({
     });
   },
   sliceDataIntoChunks(data, chunkSize) {
-    console.log("发送图片数据:", data.byteLength)
+    let buffer = data;
+    console.log("发送壁纸数据:", buffer.byteLength, buffer.length)
+    let total = buffer.byteLength || buffer.length
     const chunks = [];
     // 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);
+    for (let i = 0; i < total; i += chunkSize) {
+      const chunk = buffer.slice(i, i + chunkSize);
       chunks.push(chunk);
     }
+    // const sliceSize = chunkSize / 2; // 每个 RGB565 占 2 字节
+    // const chunks = [];
+    // for (let i = 0; i < total; i += sliceSize) {
+    //   chunks.push(buffer.slice(i, i + sliceSize));
+    // }
     this.data._chunks = chunks;
   },
 
@@ -282,29 +400,9 @@ Page({
     let btHelper = BtHelper.getInstance();
     let i = 0;
     _this.data._timer = setInterval(async () => {
-      if (i >= chunks.length) {
-        clearInterval(_this.data._timer);
-        console.log("发送图片数据完成:", i, total)
-        return;
-      }
-      const chunk = chunks[i];
-      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);
-
-      let res = await btHelper.wallPaperSyncData(chunk);
-      // let res = true;
-      // btHelper.wallPaperData(chunk);
-
-      let nowDate = Date.now()
-      if (i === chunks.length - 1 && res) {
+      if (i > chunks.length - 1) {
         wx.showModal({
-          title: '图片上传成功' + i + " / " + nowDate,
+          title: '壁纸上传成功:' + i + "总:" + chunks.length,
           showCancel: false,
           success(res) {
             if (res.confirm) {
@@ -324,35 +422,49 @@ Page({
           }
         })
         _this.endImage(0)
+        return;
+      }
 
-      } else if (!res) {
+      const chunk = chunks[i];
+      next += (chunk.byteLength ?? chunk.length);
+      // let uint8Array = new Uint8Array(chunk);
+      // let unit16 = uint8Array.map(item => {
+      //   return item.toString(16)
+      // });
+      console.log("发送壁纸数据1:", i, ":", next, ":", chunk.length, ":", chunk.byteLength, ":", total, chunks.length)
+
+      let res = await btHelper.wallPaperSyncData(chunk);
+      // let res = true;
+      // btHelper.wallPaperData(chunk);
+
+      if (!res) {
         wx.showModal({
-          title: '图片上传失败',
+          title: '壁纸上传失败',
           showCancel: false
         })
-
         _this.endImage(2)
       }
+      _this.updateProgress(next, total);
+
       i++;
-    }, 20);
+    }, 5);
   },
   async delay(ms) {
     return new Promise(resolve => setTimeout(resolve, ms));
   },
   endImage(value) {
     let _this = this
-    console.log("结束图片上传:", value)
+    // console.log("结束壁纸上传:", value)
     if (_this.data._timer) {
       clearInterval(_this.data._timer)
       _this.data._timer = null
     }
+    _this.setData({
+      progress: 0,
+      showProgress: false
+    })
     _this.data._chunks = []
     BtHelper.getInstance().wallPaper(value);
-    if (value === 0) {
-
-    } else {          // 获取页面栈
-
-    }
   },
   startProgress() {
     this.setData({
@@ -365,13 +477,9 @@ Page({
     let _this = this
     if (chunk >= total) {
       _this.setData({
-        progress: 0,
-        showProgress: false,
-        // showCropImg: false
+        progress: 100,
+        showCropImg: false
       });
-      wx.showToast({
-        title: '图片上传成功',
-      })
     } else {
       _this.setData({
         progress: progress,
@@ -388,7 +496,7 @@ Page({
     // this.setData({
     //   scr:json,
     // })
-    this.upload(); //上传图片
+    this.upload(); //上传壁纸
 
     let _this = this;
     EventManager.addNotification(CmdEvent.eventName, function (event) {
@@ -406,13 +514,21 @@ Page({
             _this.sendImage()
             _this.startProgress()
           } else if (otaCmd === 0 && kind == 1) {
+            _this.setData({
+              progress: 0,
+              showCropImg: false
+            });
             // 发送结束
           } else if (kind == 0) {
             wx.hideLoading()
             wx.showModal({
-              title: '图片上传失败了',
+              title: '壁纸上传失败了',
               showCancel: false
             })
+            _this.setData({
+              progress: 0,
+              showCropImg: false
+            });
             if (_this.data._timer) {
               clearInterval(_this.data._timer)
               _this.data._timer = null