uniapp 安卓原生截图保存到相册跟api服务器 canvas实现 plus.nativeObj.Bitmap实现

复制代码
// 截图plus.nativeObj.Bitma

// const handleScreenshot = () => {
//   try {
//     const timestamp = new Date().getTime()
//     const filePath = `_doc/screenshot_${timestamp}.png`
//     const currentPages = getCurrentPages()
//     const currentPage = currentPages[currentPages.length - 1]
//     const webview = currentPage.$getAppWebview() // 获取当前页面 webview
//     const bitmap = new plus.nativeObj.Bitmap('screenshot_' + timestamp)
//     webview.draw(
//       bitmap,
//       () => {
//         // 保存到本地 _doc/
//         bitmap.save(
//           filePath,
//           { overwrite: true, format: 'png' },
//           (res) => {
//             console.log('截图保存成功', res.target)

//             // 保存到手机相册
//             plus.gallery.save(res.target, (galleryRes) => {
//               console.log('已保存到相册:', galleryRes)
//               uni.showToast({ title: '已保存到相册', icon: 'success' })
//             }, (galleryErr) => {
//               console.error('保存相册失败', galleryErr)
//             })

//             // 上传到服务器
//             uni.uploadFile({
//               url: 'http://xxxxxx:8090/photo/upload',
//               filePath: res.target,
//               name: 'file',
//               success: (uploadRes) => uni.showToast({ title: '已到媒体库', icon: 'success' }) ,
//               fail: (err) => console.error('上传失败', err)
//             })

//             // 释放 bitmap 资源
//             bitmap.clear()
//           },
//           (err) => {
//             console.error('保存 _doc/ 失败', err)
//             bitmap.clear()
//           }
//         )
//       },
//       (err) => {
//         console.error('截图 draw 失败', err)
//         bitmap.clear()
//       }
//     )
//   } catch (error) {
//     console.error('截图异常', error)
//   }
// }


// 截图 canvas
// const handleScreenshot = () => {
//   try {
//     const timestamp = new Date().getTime()
//     const canvasId = 'drawCanvas'          // 你的 canvas-id
//     const filePath = `_doc/screenshot_${timestamp}.png`

//     // 使用 uniApp 官方 API 生成临时文件
//     uni.canvasToTempFilePath({
//       canvasId,
//       fileType: 'png',
//       success: (res) => {
//         console.log('canvas 截图成功', res.tempFilePath)

//         // 保存到本地 _doc/
//         const tempPath = res.tempFilePath

//         // 保存到手机相册
//         plus.gallery.save(tempPath, 
//           () => {
//             console.log('已保存到相册:', tempPath)
//           }, 
//           (err) => {
//             console.error('保存到相册失败', err)
//           }
//         )

//         // 上传到服务器
//         uni.uploadFile({
//           url: 'http://xxxxx/photo/upload',
//           filePath: tempPath,
//           name: 'file',
//           success: (uploadRes) => console.log('上传成功', uploadRes),
//           fail: (err) => console.error('上传失败', err)
//         })
//       },
//       fail: (err) => {
//         console.error('canvas 截图失败', err)
//       }
//     })
//   } catch (error) {
//     console.error('截图异常', error)
//   }
// }

两个绘制跟界面合成一张图截图-实现

复制代码
<template>
  <view >  
          <view @click="handleScreenshot">截图</view>
  <canvas canvas-id="canvasMerge" width="750" height="517"
      style="width:750rpx;height:517rpx;position:absolute;left:-9999px;top:-9999px;"></canvas>
  </view>
</template>


let imgPath1 = ref('')
let imgPath2 = ref('')
const screenshotBitmap = async () => {
  return new Promise((resolve, reject) => {
    try {
      const timestamp = new Date().getTime()
      const filePath = `_doc/screenshot_bitmap_${timestamp}.png`
      const currentPages = getCurrentPages()
      const currentPage = currentPages[currentPages.length - 1]
      const webview = currentPage.$getAppWebview()
      const bitmap = new plus.nativeObj.Bitmap('screenshot_' + timestamp)

      webview.draw(
        bitmap,
        () => {
          bitmap.save(
            filePath,
            { overwrite: true, format: 'png' },
            (res) => {
              imgPath1.value = res.target
              bitmap.clear()
              resolve(res.target)
            },
            (err) => {
              bitmap.clear()
              reject(err)
            }
          )
        },
        (err) => {
          bitmap.clear()
          reject(err)
        }
      )
    } catch (error) {
      reject(error)
    }
  })
}
// ------------------------
// 截图 canvas
// ------------------------
const screenshotCanvas = async (canvasId = 'drawCanvas') => {
  return new Promise((resolve, reject) => {
    try {
      const timestamp = new Date().getTime()
      plus.io.resolveLocalFileSystemURL('_doc/', (docEntry) => {
        const fileName = `screenshot_canvas_${timestamp}.png`
        uni.canvasToTempFilePath({
          canvasId,
          fileType: 'png',
          success: (res) => {
            plus.io.resolveLocalFileSystemURL(res.tempFilePath, (entry) => {
              entry.copyTo(
                docEntry,
                fileName,
                (newEntry) => {
                  imgPath2.value = newEntry.toLocalURL()
                  resolve(newEntry.toLocalURL())
                },
                (err) => reject(err)
              )
            }, (err) => reject(err))
          },
          fail: (err) => reject(err)
        })
      }, (err) => reject(err))
    } catch (error) {
      reject(error)
    }
  })
}
// 合成截图
const mergeScreenshots = async (path1, path2) => {
  const systemInfo = uni.getSystemInfoSync()
  const canvasWidthPx =systemInfo.screenWidth 
  const canvasHeightPx = systemInfo.screenHeight 

  return new Promise((resolve, reject) => {
    try {
      const ctx = uni.createCanvasContext('canvasMerge')
      ctx.clearRect(0, 0, canvasWidthPx, canvasHeightPx)
      ctx.drawImage(path1, 0, 0, canvasWidthPx, canvasHeightPx)
      ctx.drawImage(path2, 0, 0, canvasWidthPx, canvasHeightPx)

      ctx.draw(false, () => {
        const timestamp = new Date().getTime()
        const fileName = `merge_${timestamp}.png`

        uni.canvasToTempFilePath({
          canvasId: 'canvasMerge',
          fileType: 'png',
          success: (res) => {
            plus.io.resolveLocalFileSystemURL('_doc/', (docEntry) => {
              plus.io.resolveLocalFileSystemURL(res.tempFilePath, (entry) => {
                entry.copyTo(
                  docEntry,
                  fileName,
                  (newEntry) => resolve(newEntry.toLocalURL()),
                  (err) => reject(err)
                )
              }, (err) => reject(err))
            }, (err) => reject(err))
          },
          fail: (err) => reject(err)
        })
      })
    } catch (error) {
      reject(error)
    }
  })
}
// ------------------------
// 点击按钮执行
// ------------------------
const handleScreenshot = async () => {
  try {
    const path1 = await screenshotBitmap()
    const path2 = await screenshotCanvas('drawCanvas')
    const mergedPath = await mergeScreenshots(path1, path2)
    // 保存到相册
    plus.gallery.save(
      mergedPath,
      () => uni.showToast({ title: '已保存到相册', icon: 'success' }),
      (err) => console.error('保存相册失败', err)
    )

    // 上传到服务器
    uni.uploadFile({
      url: 'http://xxxx:8090/photo/upload',
      filePath: mergedPath,
      name: 'file',
      success: (res) => console.log('上传成功', res),
      fail: (err) => console.error('上传失败', err)
    })
  } catch (error) {
    console.error('截图/合成异常', error)
  }
}
相关推荐
HLC++11 小时前
Linux的进程间通信
android·linux·服务器
爱笑鱼15 小时前
Binder(二):AIDL 生成的 Proxy、Stub 和 Parcel 到底在做什么?
android
爱笑鱼15 小时前
Binder(一):一次方法调用,究竟怎样跨进程执行?
android
壮哥_icon16 小时前
【Android 系统开发】使用 BAT 脚本高效自动化管理 /system/priv-app/ 系统应用(安装与卸载)
android·运维·自动化
用户693717500138417 小时前
Claude Code终端日志Token占用实测:一个过滤器砍掉60%-90%
android·前端·后端
蝉蜕日记18 小时前
AccumuPDF高级版 v2.57 | 视图文转换PDF,合并分割压缩
android·智能手机·pdf·生活·软件需求
吐了啊取名字太难18 小时前
美颜系统AI修图本地跑并支持Mac、win、安卓、iOS不卡顿
android·人工智能·windows·数码相机·mac·ai编程
阿pin19 小时前
Android随笔-Retrofit
android·retrofit
想取一个与众不同的名字好难19 小时前
安卓自定义颜色选择器
android
我命由我1234520 小时前
Android 开发问题:java.lang.NoSuchMethodError:No virtual method readAllBytes()
android·java·java-ee·kotlin·android studio·android-studio·android runtime