【前端】Canvas画布实现在线的唇膏换色功能

【前端】Canvas画布实现在线的唇膏换色功能

推荐超级课程:

  • 本地离线DeepSeek AI方案部署实战教程【完全版】
  • Docker快速入门到精通
  • Kubernetes入门到大师通关课
  • AWS云服务快速入门实战

目录

  • 【前端】Canvas画布实现在线的唇膏换色功能
    • 背景概述
    • 以下是我们的实现方法!
      • 第一步 — 找到灰度唇部图像
      • 第二步 — 创建一个画布
      • 第三步 — 加载唇部图像
      • 第四步 — 在我们的画布上绘制图像
      • 第五步 — 在‘hiddenCanvas’上完成图像着色操作
    • 颜色
    • 差异
    • 叠加
    • 乘法
      • 第六步 — 在真实画布上绘制唇部
      • 第七步 — 将着色的唇部放置在脸上
    • 结语

背景概述

===================

在我们的网站上销售美容产品,必须要帮助客户从种类中选择正确产品。
对于美容产品来说,用户通过屏幕上的图片做出正确的选择至关重要。例如,用户可能想知道某款唇色涂抹在特定肤色上会是什么样子。

解决这个问题有多种方法。

  • 我们可以为每种唇色准备一张图片,并在用户浏览色板时更换图片。这种方法可行,但会影响网站性能。更快的页面意味着更好的用户体验。每次为数百种颜色变体加载图片会在低带宽网络上造成不必要的延迟,从而影响用户体验。
  • 我们也可以使用SVG,然后在上面应用颜色,但这种方法的一个挑战是,对于唇色这样的用例,细线和阴影看起来会“动画化”,结果会显得有些不自然。
  • 为了确保用户看到的颜色和唇形尽可能真实,我们使用了PNG图片,将这些PNG像素转换成所需的颜色,并使用画布来应用颜色,这样做速度很快!以下是我们取得的成果!

在这里插入图片描述

以下是我们的实现方法!

=====================

让我们逐步探索Canvas API,在本教程结束时,你可以使用这种简单技术在你的网站上解决类似的问题。

第一步 — 找到灰度唇部图像

=========================================

首先,我们需要一张唇部图像,我们将在上面尝试不同的颜色。
在这里插入图片描述

这里我们开始!由于图像是灰度的,我们在应用任何颜色之前不需要计算任何东西。如果图像不是灰度的,我们需要先将图像转换为灰度,然后继续。

我们确保在给唇部上色时不会扭曲细线和阴影,否则它会看起来不自然。

第二步 — 创建一个画布

==========================

让我们编写一些代码来创建一个画布。

这是HTML标记:

<div><canvas id=”finalCanvas” />
</div>
<div style="display: none"><canvas id=”hiddenCanvas” />
</div>

在这个HTML标记中,你可以看到两个画布元素,一个名为‘finalCanvas’,另一个名为‘hiddenCanvas’。我们将使用‘hiddenCanvas’来绘制唇部图像,然后在上面添加颜色,最后将其映射回‘finalCanvas’。

我们需要两个画布,因为我们在这里使用了一个两遍算法。在第一遍中,我们用所需颜色绘制整个画布,在第二遍中,我们将画布裁剪以适应最终的‘finalCanvas’。

第三步 — 加载唇部图像

==============================

const image = new Image();
image.crossOrigin = ‘Anonymous’;
image

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

异步编程与流水线架构:从理论到高并发

目录 一、异步编程核心机制解析 1.1 同步与异步的本质区别 1.1.1 控制流模型 1.1.2 资源利用对比 1.2 阻塞与非阻塞的技术实现 1.2.1 阻塞I/O模型 1.2.2 非阻塞I/O模型 1.3 异步编程关键技术 1.3.1 事件循环机制 1.3.2 Future/Promise模式 1.3.3 协程&#xff08;Cor…

字节跳动算法高频题:动态规划最优模板

本文系统梳理字节跳动近三年算法面试中的动态规划&#xff08;DP&#xff09;高频题型&#xff0c;提炼出适用于80%场景的通用解题模板。通过背包问题、字符串处理、状态压缩等六大核心模块解析&#xff0c;结合跳槽、股票交易、编辑距离等15道真题案例&#xff0c;揭示动态规划…

QT网页显示的几种方法及对比

一.直接跳转打开网页 1.使用QDesktopServices::openUrl调用系统浏览器 原理&#xff1a;直接调用操作系统默认浏览器打开指定URL&#xff0c;不在应用程序内嵌入网页。 优点&#xff1a; 实现简单&#xff0c;无需额外模块或依赖。 适用于仅需跳转外部浏览器的场景。 缺点&…

【赵渝强老师】在Docker中运行达梦数据库

Docker是一个客户端服务器&#xff08;Client-Server&#xff09;架构。Docker客户端和Docker守护进程交流&#xff0c;而Docker的守护进程是运作Docker的核心&#xff0c;起着非常重要的作用&#xff08;如构建、运行和分发Docker容器等&#xff09;。达梦官方提供了DM 8在Doc…

python转换wav到mp3

尺寸好大&#xff0c;8G多&#xff0c;但是&#xff0c;领动的车机不识别.wav格式的音乐。 用python转换一下。 import os from pydub import AudioSegment filesos.listdir(E:\\dy2023) for f in files:if f.endswith(.wav):try:wavAudioSegment.from_wav(E:\\dy2023\\%s % f…

创建自己的github.io

1、创建GitHub账号 GitHub地址&#xff1a;https://github.com/ 点击Sign up创建账号 如果已创建&#xff0c;点击Sign in登录 2、创建仓库 假设Owner为username&#xff0c;则Repository name为username.github.io说明&#xff1a; 1、Owner为用户名 2、Repository name为仓…

Linux系统docker部署Ollama本地大模型及部署Hugging Face开源模型,ollama相关注意点,非ollama模型创建,模型量化,显存建议

本文主要描述在Linux系统使用docker部署ollama自有模型以及Hugging Face开源模型&#xff0c;也涉及到一些相关注意点&#xff0c;欢迎沟通讨论~ 拉取镜像 拉取ollama最新镜像&#xff1a;docker pull ollama/ollama:latest 运行ollama 执行&#xff1a;docker run -d --res…

在 Elasticsearch 中扩展后期交互模型 - 第 2 部分 - 8.18

作者&#xff1a;来自 Elastic Peter Straer 及 Benjamin Trent 本文探讨了如何优化后期交互向量&#xff0c;以适应大规模生产工作负载&#xff0c;例如减少磁盘空间占用和提高计算效率。 在之前关于 ColPali 的博客中&#xff0c;我们探讨了如何使用 Elasticsearch 创建视觉搜…

JAVA泛型的作用

‌1. 类型安全&#xff08;Type Safety&#xff09;‌ 在泛型出现之前&#xff0c;集合类&#xff08;如 ArrayList、HashMap&#xff09;只能存储 Object 类型元素&#xff0c;导致以下问题&#xff1a; ‌问题‌&#xff1a;从集合中取出元素时&#xff0c;需手动强制类型转…

深入理解 JavaScript/TypeScript 中的假值(Falsy Values)与逻辑判断 ✨

&#x1f579;️ 深入理解 JavaScript/TypeScript 中的假值&#xff08;Falsy Values&#xff09;与逻辑判断 在 JavaScript/TypeScript 开发中&#xff0c;if (!value) 是最常见的条件判断之一。它看似简单&#xff0c;却隐藏着语言的核心设计逻辑&#xff0c;也是许多开发者…

【AI速读】30分钟搭建持续集成:用Jenkins拯救你的项目

每个开发者都踩过的坑 你有没有这样的经历?花了一周时间改代码,自信满满准备提交,结果合并同事的更新后,项目突然编译失败,测试跑不通。你焦头烂额地排查问题,老板还在催进度……但明明不是你的错! 这种“集成地狱”几乎每个团队都遇到过。传统的手动集成方式(比如每周…

doris:负载均衡

用户通过 FE 的查询端口&#xff08;query_port&#xff0c;默认 9030&#xff09;使用 MySQL 协议连接 Doris。当部署多个 FE 节点时&#xff0c;用户可以在多个 FE 之上部署负载均衡层来实现 Doris 查询的高可用。 本文档介绍多种适用于 Doris 的负载均衡方案&#xff0c;并…

【大语言模型_6】mindie启动模型错误整理

一、启动报 [hccl_runner.cpp:141] AllGatherHcclRunner:0 HcclCommInitRootInfo fa il, error:2, rank:0, rankSize:2 背景&#xff1a;运行DeepSeek-R1-Distill-Qwen-14B模型&#xff0c;在2张300 P卡可以运行&#xff0c;单独一张启动报以上错误。 问题分析&…

dcat-admin已完成项目部署注意事项

必须 composer update 更新项目php artisan admin:publish 发布dcatadmin的静态资源手动创建目录&#xff08;如果没有&#xff09; storage/appstorage/framework/cachestorage/framework/sessionsstorage/framework/views 需检查 php不要禁用以下函数 putenvsymlinkproc_…

【计算机网络】网络简介

文章目录 1. 局域网与广域网1.1 局域网1.2 广域网 2. 路由器和交换机3. 五元组3.1 IP和端口3.2 协议3.3 协议分层 4. OSI七层网络协议5. TCP/IP五层模型5.1 TCP/IP模型介绍5.2 网络设备所在分层 6. 封装与分用6.1 数据包的称谓6.2 封装6.3 分用 1. 局域网与广域网 1.1 局域网 …

在QT中进行控件提升操作

目录 一、概述 二、功能需求 三、提升操作 1&#xff09;拖入标准控件 2&#xff09;自定义类 3&#xff09;提升控件 一、概述 QT中提供的标准控件能够满足我们大多数情况下的功能需求&#xff0c;但是在一些特殊应用场合&#xff0c;我们可能需要对控件的功能进行扩展&am…

如何自定义知行之桥Webhook端口返回的Response消息

一、Webhook端口功能概述 知行之桥的Webhook端口提供灵活的消息响应机制&#xff0c;支持用户通过修改配置文件自定义返回的消息体内容&#xff0c;能够查看是否调用接口成功、数据是否推送成功以及自定义返回给用户端的响应内容。 本指南将详解如何通过脚本配置实现以下需求…

pnpm config set ignore-workspace-root-check true

异常 ERR_PNPM_ADDING_TO_ROOT  Running this command will add the dependency to the workspace root, which might not be what you want - if you really meant it, make it explicit by running this command again with the -w flag (or --workspace-root). If you don…

【iOS】SwiftUI 路由管理(NavigationStack)

QDRouter.swift import SwiftUIMainActor class QDRouter: ObservableObject {Published var path NavigationPath()static let main QDRouter() // 单例private init() {}func open(_ url: String) {guard let url URL(string: url) else {return}UIApplication.shared.op…

蓝桥杯学习-13回溯

13回溯 一、回溯1 例题1–递归实现排列型枚举-蓝桥19684 1.递归可以解决不定次数的循环问题 2.使用数组来标记数字是否被选过import java.util.Scanner;public class Main {static int n;static boolean[] st new boolean[10]; //判断数字是否被选过static int[] path ne…