0

    h5如何实现下载图片(网页截图+下载图片到手机相册)

    2023.05.26 | admin | 154次围观

    前言

    最近在做的项目(移动端h5),产品有个这样的需求(参考淘宝的):

    点击下载按钮,保存一个卡片式的图片到手机上

    点击保存照片:

    保存到手机相册的照片:

    好了,需求都清楚了,那就开始实现吧~

    实现

    先梳理下实现思路,既然想保存一个卡片式的图片到手机上为什么当前页面不支持长截屏,那么我们就要先有这个卡片式的页面。再通过网页截图的方式生成图片。最后再进行下载到手机上。

    好了为什么当前页面不支持长截屏,那么我们只需要做到以下两步即可:

    网页截图生成卡片式图片下载这张图片网页截图生成图片

    采用html2canvas + canvas.toBlob来实现。

    1、安装

    npm i html2canvas --save
    

    2、创建卡片组件

    card.vue

    
    

    3、图片生成+下载

    在页面中引用

    
    <script>
    import card from "./card.vue";
    import { convertToImage, saveBlob } from "@/utils/convertToImage";
    export default {
        components: { card },
        methods: {
            async saveImg() {
              let element = document.getElementById("saveHtml");
              // 调用函数,取到截图的blob数据,对图片进行处理(保存本地、展示等)
              const blob = await convertToImage(element);
              
              // 下载图片到手机
              saveBlob(blob, "访客凭证");
            },
        }
    }
    script>
    

    需求是点击下载,就保存卡片式的图片到手机上。

    h5如何实现下载图片(网页截图+下载图片到手机相册)

    要想实现这点,我们就需要将我们的card卡片隐藏,视觉内看不到。

    // 下载图片
    #saveHtml {
      position: absolute;
      top: 0;
      height: 570px;
      z-index: -10;
    }
    

    使用html2canvas进行截图

    import html2canvas from "html2canvas";
    // 生成快照
    export const convertToImage = (container, options = {}) => {
      // 设置放大倍数
      const scale = window.devicePixelRatio;
      // 传入节点原始宽高
      const _width = container.offsetWidth;
      const _height = container.offsetHeight;
      let { width, height } = options;
      width = width || _width;
      height = height || _height;
      // html2canvas配置项
      const ops = {
        scale,
        width,
        height,
        useCORS: true,
        allowTaint: false,
        ...options
      };
      
      return html2canvas(container, ops).then(canvas => {
        // 返回图片的blob数据
        return new Promise(function(resolve) {
          canvas.toBlob(function(blob) {
            resolve(blob)
          })
        })
      });
    }
    

    有个点需要解释下:

    1、为什么使用canvas.toBlob来生成图片,而不是用canvas.toDataURL来生成呢?

    答:使用canvas.toDataURL生成base64格式的图片,无法在移动端下载,PC端Chrome可以(其他类型浏览器未测试)。

    下载图片

    // 下载图像
    export const saveBlob = (blob, fileName) => {
      const a = document.createElement('a');
      a.style.display = 'none';
      const url = window.URL.createObjectURL(blob);
      a.href = url;
      a.download = fileName;
      a.click();
    }
    

    获取到截图的blob数据后,使用URL.createObjectURL()将blob数据生成一个图片url,最后使用a标签的download属性下载图片。

    到此,其实就已经实现了图片生成和下载。

    4、优化

    在安卓机和苹果机上都进行了测试。

    测试结果:在安卓机上可以下载图片,但在苹果机上无法下载到手机中。

    优化思路:

    安卓机上还是直接调用a标签下载图片苹果机上使用弹框预览图片,让用户长按图片使用手机自带的保存图片功能保存图片到手机上。

    在页面中添加一个预览弹框

    <van-dialog
          v-model="isIPhone"
          :showConfirmButton="false"
          :closeOnClickOverlay="true"
        >
          <img :src="img" />
          <p class="textCenter">“长按”保存照片到手机p>
    van-dialog>
    

    获取到blob数据后,分步处理

    // 判断是否ios
    // 在ios移动端上直接预览图片,长按图片保存(ios系统不支持直接下载)
    if (browser.versions.mobile && browser.versions.ios) {
        this.img = window.URL.createObjectURL(blob);
        this.isIPhone = true;
    } else {
        // 安卓机和网页端都直接下载到手机相册中
        saveBlob(blob, "访客凭证");
    }
    

    经过安卓和苹果机的实测,效果不错。

    小记

    时刻记录着,因为代码值得~

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    发表评论