微信小程序预览图片和H5使用canvas实现图片+蒙层+文字

1、效果

2.H5实现

<!--
 * @Author: limingfang
 * @Date: 2024-05-20 10:26:51
 * @LastEditors: limingfang
 * @LastEditTime: 2024-05-21 16:31:11
 * @Description: 
-->
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">  
    <title>Canvas Draw Image and Elements</title>  
    <style>
        body {
            padding: 0;
            margin: 0;
        }
    </style>
</head>  
<body>  
    <canvas id="myCanvas" width="375" height="375"></canvas>  
  
    <script>  
        const canvas = document.getElementById('myCanvas');  
        const ctx = canvas.getContext('2d');  
  
        // 加载图片  
        const img = new Image();  
        img.onload = function() {  
            // 绘制图片  
            ctx.drawImage(img, 0, 0, 375, 375); // 参数:图片对象, x坐标, y坐标, 宽度, 高度  
  
            // 绘制文本  
            ctx.font = '28px Arial';  
            ctx.fillStyle = '#767B8D';  
            ctx.fillText('处方药', 146, 174);  
            ctx.fillText('依法不展示包装', 90, 222);  
            ctx.filter = 'blur(5px)';
  
            // 导出为图片(可选)  
            const dataUrl = canvas.toDataURL('image/png');  
            console.log(dataUrl,'dataUrl00000000000000000000');
            // 你可以使用dataUrl进行进一步的操作,例如将其设置为img元素的src属性  
            const imgElement = document.createElement('img');  
            imgElement.src = dataUrl;  
            imgElement.style.filter = 'blur(5px)';  
            document.body.appendChild(imgElement);  
        };  
        img.src = './4.jpg'; // 替换为你的图片路径  
		img.crossOrigin = "anonymous";//添加此行anonymous必须小写
    </script>  
</body>  
</html>

3.小程序实现

        <swiper indicator-color="#efeff4" indicator-active-color="#f16a33" circular="true" interval="2000" duration="600" bindchange="handleSwiperChange">
          <block wx:for="{{ json_data.goods[0].images }}" wx:key="index" wx:for-index="index" wx:for-item="item">
            <swiper-item>
              <image src="{{ filter.formattingPictureThumbnail(['750', '750'], item.img_url) }}" class="swiper-image" 
              data-index="{{index}}"
              catchtap="previewMedia"
              mode="aspectFit" />
              <view catchtap="previewMedia" data-index="{{index}}" wx:if="{{json_data.medicinesIsPrescribe&&mark.markFlag}}" class="d6-goods-img-no absolute left-0 top-0 w-full text-center box-border" style="-webkit-backdrop-filter: blur({{mark.markTransparency}}px);backdrop-filter:blur({{mark.markTransparency}}px);">
                <view catchtap="previewMedia" data-index="{{index}}">
                  <view catchtap="previewMedia" data-index="{{index}}">处方药</view>
                  <view catchtap="previewMedia" data-index="{{index}}">依法不展示包装</view>
                </view>
              </view>
            </swiper-item>
          </block>
        </swiper>
/**
   * 绘制canvas图片+图片阴影+蒙层
   * @returns 
   */
  initCanvasImages(){
    let images = this.data.json_data?.goods && this.data.json_data?.goods[0]?.images || [];
    if(images.length <= 0) return;
    let sources = [];
    const _this = this;
    if (this.data.json_data.medicinesIsPrescribe && this.data.mark.markFlag) {
      // 获取canvas上下文  
      wx.createSelectorQuery()
      .select('#goodsCanvas')
      .fields({
        node: true,
        size: true,
      })
      .exec((canvasRes)=>{
        if(canvasRes.length <= 0) return;
        const canvas = canvasRes[0].node;
        const ctx = canvas.getContext('2d');

        // 设置canvas的宽度和高度与图像相同  
        canvas.width = 375;  
        canvas.height = 375;  

        images.forEach((item,index) => {
            images[index] = canvas.createImage();
            images[index].onload = function() {

            // 简单模糊处理(非高斯模糊): 只是多次绘制图片来模拟模糊效果
            for (let i = 0; i < _this.data.mark.markTransparency; i++) { // 重复次数越多,模糊效果越明显  
              ctx.globalAlpha = 1 / (i + 1); // 每次绘制时降低透明度  
              ctx.drawImage(images[index], i, i, 375, 375); // 参数:图片对象, x坐标, y坐标, 宽度, 高度  
            }  
            // 重置透明度  
            ctx.globalAlpha = 0.2;  
            ctx.filter = `blur(${_this.data.mark.markTransparency})px`;

            // 绘制文本  
            ctx.font = '28px Arial';
            ctx.fillStyle = '#767B8D';
            ctx.fillText('处方药', 146, 168);
            ctx.fillText('依法不展示包装', 90, 210);

            const dataUrl = canvas.toDataURL('image/png', 0.5); 
            sources[index] = {
              url: dataUrl,
              type: item.img_type === 3 ? 'image' : 'video'
            };

            // 清除画布内容  
            ctx.clearRect(0, 0, 375, 375); // 清除画布上的所有内容,参数是画布的宽高  
            };
            images[index].src = item.img_url;
        })
      });
    } else {
      sources = images.map(item => ({
        url: item.img_url,  // 图片或视频的地址
        type: item.img_type === 3 ? 'image' : 'video' // 需要预览的资源类型
      }));
    }
    this.setData({
      canvasImages: sources
    });
  },
  /**
   * 预览图片/video
   */
  async previewMedia(e) {
    let current = e.target.dataset.index;
    wx.previewMedia({
      sources: this.data.canvasImages, // 需要预览的资源列表
      current // 当前显示的资源序号
    })
  },

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/644166.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

sysbench压测mysql性能测试命令和报告

sysbench压测mysql性能测试命令和报告 一、安装sysbench工具二、创建测试数据库三、基于sysbench构造测试表和测试数据四、数据库性能测试1、数据库读写性能测试2、数据库读性能测试3、数据库删除性能测试4、数据库更新索引字段性能测5、数据库更新非索引字段性能测试6、数据库…

Redis内存回收-内存淘汰策略

LFU的访问次数之所以叫做逻辑访问次数&#xff0c;是因为并不是每次key被访问都计数&#xff0c;而是通过运算&#xff1a; 生成0~1之间的随机数R计算 (旧次数 * lfu_log_factor 1)&#xff0c;记录为P如果 R < P &#xff0c;则计数器 1&#xff0c;且最大不超过255访问…

ASP+ACCESS多功能论坛程序设计

摘 要 随着计算机的广泛应用&#xff0c;人们已经对网络不再感到陌生。在科技飞速发展的今天&#xff0c;电脑信息技术与各行各业进行了有效的结合。人们在网上可以进行网上购物&#xff0c;网上交友&#xff0c;电子商务&#xff0c;网络营效等等。面对强大的网络功能&#x…

@Async详解,为什么生产环境不推荐直接使用@Async?

一、Async 注解介绍&#xff1a; Async 注解用于声明一个方法是异步的。当在方法上加上这个注解时&#xff0c;Spring 将会在一个新的线程中执行该方法&#xff0c;而不会阻塞原始线程。这对于需要进行一些异步操作的场景非常有用&#xff0c;比如在后台执行一些耗时的任务而不…

Vue3实战笔记(45)—VUE3封装一些echarts常用的组件,附源码

文章目录 前言一、柱状图框选二、折线图堆叠总结 前言 日前使用hooks的方式封装组件&#xff0c;在我使用复杂的图标时候遇到了些问题&#xff0c;预想在onMounted中初始化echarts&#xff0c;在使用hooks的时候&#xff0c;组件没有渲染完&#xff0c;使用实例会出现各种各样…

ArcGIS中分割与按属性分割的区别

1、分割ArcGIS批量导出各个市的县级行政边界 视频教学&#xff1a; ArcGIS批量导出各个市的县级行政边界002 2、ArcGIS批量导出全国各省的边界 视频教学&#xff1a; ArcGIS导出全国各省的边界003 推荐学习&#xff1a; ArcGIS全系列实战视频教程——9个单一课程组合系列直播回…

文章解读与仿真程序复现思路——电力系统保护与控制EI\CSCD\北大核心《计及温控厌氧发酵和阶梯碳交易的农村综合能源低碳经济调度》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Vite + Vue3 部署 GitHub

因为静态资源是可以部署到 GitHub 上&#xff0c;自己顺便学习部署网站 因为我使用的是 Vite 工具&#xff0c;官方有提供相应 Demo 部署静态站点 | Vite 官方中文文档 新建文件夹 .github 然后再建一个文件夹 workflows 新建文件 main.yml 文件 直接使用官方文档 demo #…

ps进程查看命令详解

1、PS 命令是什么 查看它的man手册可以看到&#xff0c;ps命令能够给出当前系统中进程的快照。它能捕获系统在某一事件的进程状态。如果你想不断更新查看的这个状态&#xff0c;可以使用top命令。 2、ps命令支持三种使用的语法格式 UNIX 风格&#xff0c;选项可以组合在一起…

「云渲染课堂」3dmax地砖材质参数怎么让画面更加真实?

在3DMAX中&#xff0c;地砖材质的渲染需要细致的调整&#xff0c;因为不同材质的地砖在反射和折射参数上各不相同。为了使地砖材质更加逼真&#xff0c;以下简要说明了一些设置方法&#xff0c;希望对大家有所帮助&#xff01; 3dmax地砖材质参数如何设置 1、打开材质编辑器&a…

Git提交和配置命令

一、提交代码到仓库 在软件开发中&#xff0c;版本控制是一个至关重要的环节。而Git作为目前最流行的版本控制系统之一&#xff0c;为我们提供了便捷高效的代码管理和协作工具。在日常开发中&#xff0c;我们经常需要将本地代码提交到远程仓库&#xff0c;以便于团队协作和版本…

C++ | Leetcode C++题解之第112题路径总和

题目&#xff1a; 题解&#xff1a; class Solution { public:bool hasPathSum(TreeNode *root, int sum) {if (root nullptr) {return false;}if (root->left nullptr && root->right nullptr) {return sum root->val;}return hasPathSum(root->left…

电磁仿真--CST网格介绍

1. 简介 网格会影响仿真的准确性和速度&#xff0c;花时间理解网格化过程是很重要的。 CST 中可用的数值方法包括FIT、TLM、FEM、MoM&#xff0c;使用不同类型的网格&#xff1a; FIT和TLM&#xff1a;六面体 FEM&#xff1a;四面体、平面 MoM&#xff1a;表面 CFD&#…

SAP揭秘者-怎么执行生产订单ATP检查及其注意点

文章摘要&#xff1a; 上篇文章给大家介绍生产订单ATP检查的相关后台配置&#xff0c;大家可以按照配置步骤去进行配置&#xff0c;配置完之后&#xff0c;我们接下来就是要执行ATP检查。本篇文章具体给大家介绍怎么来执行生产 订单ATP检查及其注意点。 执行生产订单ATP检查的…

618快到了,送大家一款自动化脚本工具,一起薅羊毛

前言 一年一次的618活动来了&#xff0c;大家做好准备了&#xff0c;奇谈君为大家准备好用的618神器&#xff0c;解放双手&#xff0c;简单操作就可以把红包拿到手。 京淘自动助手 首次使用前需要进行设置 将手机的无障碍权限和悬浮窗权限打开 设置完成后&#xff0c;可以把…

自定义一个复杂的React Table表格组件-06

前面基本了解了组件的基本用法&#xff0c;在本节会实现一个更高级的例子。另外需要注意本节代码是采用V15版本的createClass()、React.DOM和JSX实现的&#xff0c;有时间的同学可以改成类实现的方式。 html的世界中最复杂的UI控制就是表格了&#xff0c;原因是table它依赖本地…

Java进阶学习笔记18——接口的注意事项

接口的多继承&#xff1a; 一个接口可以同时继承多个接口。 package cn.ensource.d11_interface_attention;public class Test {public static void main(String[] args) {// 目标&#xff1a;理解接口的多继承} }// 接口是多继承的 interface A{void test1(); } interface B{…

【排序算法】——归并排序(递归与非递归)含动图

制作不易&#xff0c;三连支持一下吧&#xff01;&#xff01;&#xff01; 文章目录 前言一.归并排序递归方法实现二.归并排序非递归方法实现 前言 这篇博客我们将介绍归并排序的原理和实现过程。 一、归并排序递归方法实现 基本思想&#xff1a; 归并排序&#xff08;MERGE-…

Tina-Linux -- 3. LVGL测试

参考韦东山 – Tina_Linux_图形系统_开发指南 Tina-linux lvgl 配置 环境配置 进入Tina-SDK根目录 source build/envsetup.sh lunch XXX平台名称 make menuconfigLVGL Gui --->Littlevgl --->< > lv_demo<*> lv_examples &#xff08;lvgl官方demo&#…

LabVIEW虚拟测试实验室开发

LabVIEW虚拟测试实验室开发 在当代的科技和工业进步中&#xff0c;测试与测量扮演着至关重要的角色。随着技术的发展&#xff0c;测试系统也变得日益复杂和成本昂贵&#xff0c;同时对测试结果的准确性和测试过程的效率要求越来越高。开发了一种基于LabVIEW的虚拟测试实验室的…