【前端】Jquery拍照,通过PHP将base64编码数据转换成PNG格式,并保存图像到本地
目录
一、需求
二、开发语言
三、效果
四、业务逻辑:
五、web端调用摄像头
六、示例代码
1、前端
2、后端
一、需求
web端使用jquery调用摄像头拍照,并使用PHP把base64编码转换成png格式图片,下载到本地。
由于js不能指定图片存储的位置,所以需要把base64图像数据传到后台,由后台存储到指定位置。
二、开发语言
前端:JS
后端:PHP
三、效果
点击“拍摄图像”按钮,自动连续拍摄10张并上传到后台,存放到指定位置,并在前端显示预览图像
四、业务逻辑:
① 前端点击“拍摄图像”按钮,开始拍照,我这里的需求是连续拍摄10张
② 前端获取到base64编码图像数据,并发送到后端
③ 后端接收到base64编码后,转换成PNG格式并保存到指定位置
④ 图片存储成功后,返回图片路径给前端
⑤ 前端显示拍摄的图像
五、web端调用摄像头
web端调用摄像头使用“webcam.js”插件,使用webcam.js调用摄像头前提是项目是https,否则没有获取摄像头的权限。
WebcamJS:jQuery移动端调用摄像头拍照插件WebcamJS
六、示例代码
1、前端
HTML:图像采集区
<style type="text/css">#open-power{transition: transform 0.3s ease-in-out; /* 添加过渡效果,使变换更平滑 */ transform-origin: center center; /* 变换原点设置为图片中心 */ width: 100%; /* 初始尺寸设置为容器宽度 */ height: auto; /* 保持图片的宽高比 */ }#imageContainer{overflow: hidden; /* 隐藏超出容器的部分 */position: relative; /* 如果需要相对于容器定位图片,可以添加这个属性 */margin: 0 auto;background:rgba(41, 123, 255, 0.06);border-radius:18px;border:1px dashed #297BFF;cursor:pointer;box-shadow:4px 4px 18px 0px rgb(0 0 0 / 8%);padding: 10px;}.main__camera-power{background: none;border-radius: 0;border: none;cursor:none;margin: 0 auto;box-shadow:none; padding: 0px;}
</style>
<div class="layui-col-md8 layui-col-sm8 layui-col-xs12"><div class="layui-row"><div class="layui-col-md12 layui-col-sm12 layui-col-xs12"><fieldset class="layui-elem-field"><legend>图像采集区</legend><div class="layui-field-box"><!-- 图像 --><div id="imageContainer"><div id="open-power" class="main__camera-power flex-center"><span class="main__camera-power--span"><img src="/home/images/camera.png" alt="power" /></span><p class="main__camera-power--hint">请开启摄像头权限</p></div></div></div></fieldset></div></div>
</div>
HTML:拍摄图像按钮
<div class="layui-col-md6 layui-col-sm6 layui-col-xs12"><div class="paizhao" style=" width: 4.5rem; height: 4rem; margin: 0 1rem; background: #F0F0F0; text-align: center; box-shadow: 4px 4px 10px #888888; font-size: 0.9rem; border-radius: 10px; cursor: pointer; color: #000; font-size: 0.9rem;" ><i class="layui-icon layui-icon-camera-fill" style="font-size: 30px; color: #555;"></i> <br/>拍摄图像</div>
</div>
HTML:图片预览区域
<style>
/* 图像预览区域 */
#results { background:#f8f8f8; }
#results > img { width: 160px; height: 120px; margin: 3px}
</style><div class="layui-row" style="width: 98%; margin: 1% auto; "><div class="layui-col-md12 layui-col-sm12 layui-col-xs12"><div style="border: 1px solid #e6e6e6; height: 120px;overflow:auto;"><div id="results" style=""><p>Your captured images will appear here...</p></div></div></div>
</div>
JS:
<script src="/home/js/jquery-1.12.3.min.js"></script>
<script src="/home/js/webcam.js" type="text/javascript" charset="utf-8"></script>// 初始化操作 设置摄像头区域
$(function(){// 获取窗口尺寸并设置摄像头宽高为80%function setCameraSize() {var windowWidth = window.innerWidth;var windowHeight = window.innerHeight;var cameraWidth = windowWidth * 0.45;var cameraHeight = windowHeight * 0.68;$("#imageContainer").css('width',cameraWidth)$("#imageContainer").css('height',cameraHeight)// 设置摄像头宽高Webcam.set({width: cameraWidth,height: cameraHeight,jpeg_quality: 90});// 附加摄像头到容器Webcam.attach('#open-power');}// 初始设置setCameraSize();// 监听窗口大小改变事件window.addEventListener('resize', setCameraSize);});// 拍摄图像
var c = 1 // 图像张数
var c2 = 1; // 图像张数
var timer = null// 开始拍照
$(".paizhao").click(function () {c = 1c2 = 1// 拍照前先清空div里已存在的图像document.getElementById('results').innerHTML = '';var yinpian = $('#yinpian').val();if (yinpian == '') {layer.msg('请先选择饮片名称', {time: 3000, icon:2});clearTimeout( timer );return false}layer.msg('图像正在采集并处理,请稍后...', {time: 3000, icon:0});tip_html = '<br/><span style="color:green">【'+yinpian+'】</span>图像正在采集并处理,请稍后...'$("#systip").prepend(tip_html)// 开始拍照take_snapshot();// 定时 每250ms拍摄一次timer = setInterval( take_snapshot, 250 );
})function take_snapshot() {// 获取饮片名称var yinpian = $('#yinpian').val();if (yinpian == '') {layer.msg('请先选择饮片名称', {time: 3000, icon:2});clearTimeout( timer );return false}Webcam.snap( function(data_uri) {// 图片保存到本地saveJpg(data_uri,yinpian)} );// 图片数量+1c = c+1if (c > 10) {// 十张采集完成,结束采集clearTimeout( timer );timer = null;}}// Base64保存为jpg
function saveJpg(base64data,yinpian) {$.ajax({url:'/index/index/saveJpg',type:'POST',dataType:'JSON',data:{img:base64data,yinpian:yinpian},success:function (res) {console.log(res)var img_html = ''if (res.code == '200') {// 把返回的图像地址追加显示到图像预览区域var img = new Image();img.src = '/'+res.datadocument.getElementById('results').appendChild( img );console.log(img)c2 = c2+1console.log(c2)if (c2 > 10) {layer.msg('10张采集完成,请调整饮片再次采集', {time: 3000, icon:1});tip_html = '<br/><span style="color:green">【'+yinpian+'】</span>图像10张采集完成,请调整图像再次采集!'$("#systip").prepend(tip_html)}}}})
}
2、后端
接收前端传来的base64编码,把base64编码数据转存成png,并存放到指定位置
/**
* base64保存为jpg
*/
public function saveJpg()
{if (request()->isPost()) {$baseImg = trim(input('post.img')); // base64编码$yinpian = trim(input('post.yinpian')); // 饮片名称if (!empty($baseImg) && !empty($yinpian)) {//图片存放的路径$path = "uploads/images/".$yinpian.'/';if (!file_exists($path)) {mkdir($path, 0700, true); //创建目录chmod($path, 0700); //赋予权限}$uid = session('uid');//确保图片名唯一,防止重名产生覆盖$imageName = 'wx_' .$uid.'_' . rand(1000, 9000) . time(). '.jpg';//判断是否有逗号 如果有就截取后半部分if (strstr($baseImg,",")){$baseImg = explode(',',$baseImg);$baseImg = $baseImg[1];}//图片路径$imageSrc= $path . $imageName;//生成文件夹和图片$r = file_put_contents($imageSrc, base64_decode($baseImg));if($r){return apiResponse('200','图像保存成功',$imageSrc);}else{return apiResponse('110','图像保存失败');}}else{return apiResponse('110','初始化失败,请刷新页面');}}else{return apiResponse('110','非法请求');}
}
如果有控制摄像头放大缩小画面的需求,可参考另外一篇【PHP】控制摄像头缩放监控画面大小,并保存可视画面为图片_代码怎么实现监控视频怎么放大画面-CSDN博客
相关文章:

【前端】Jquery拍照,通过PHP将base64编码数据转换成PNG格式,并保存图像到本地
目录 一、需求 二、开发语言 三、效果 四、业务逻辑: 五、web端调用摄像头 六、示例代码 1、前端 2、后端 一、需求 web端使用jquery调用摄像头拍照,并使用PHP把base64编码转换成png格式图片,下载到本地。 由于js不能指定图片存储的…...
websocket再项目中的使用
WebSocket在项目中的使用主要包括以下几个方面: WebSocket的基本概念和原理: 定义:WebSocket是一种基于TCP的协议,实现了浏览器与服务器之间的全双工通信。它通过HTTP/1.1协议的101状态码进行握手,建立连接…...
ajax同步执行async:false无效的解决方法
无效的情况: function ManHourCheck() {var StartDate $("#StartDate").val();//日报日期var EndDate $("#EndDate").val();//完成日期var UserID $("#UserID").val();//员工ID$.ajax({async: false,//加了这一行也没用!!!!!!!!!!…...

基于Qt的登陆界面设计
目标 自由发挥登录界面的应用场景,实现一个登录窗口的界面。 要求:每行代码都要有注释 代码 // 设置窗口大小为600x400像素 this->resize(600,400); // 设置窗口标题为"TheWitcher 巫师3:狂猎" this->setWindowTitle(&qu…...

HarmonyOS 输入框组件:TextInput 和 TextArea 深度解析
输入框组件是移动端开发中最常见的组件之一,常用于响应用户的输入操作,比如评论区的文本输入、聊天框的消息输入、表单内容填写等场景。在 HarmonyOS 中,TextInput 和 TextArea 分别用于单行和多行输入操作。除此之外,它们还可以与…...
【Golang】 Go 语言中的 Struct、JSON 和 Map 互转:详细指南
Go 语言中的 Struct、JSON 和 Map 互转:详细指南 在 Go 语言中,处理 JSON 数据、结构体类型和映射(map)是与 API、配置或数据库交互时非常常见的任务。理解如何在这些数据类型之间无缝转换对于高效的 Go 编程至关重要。以下是如何将 Go 结构体转换为 JSON、将 JSON 转换为…...

Azure Function流式返回
最近用azure function做了一个api和llm交互,需要流式返回。但是默认不支持流返回,搜索了一下。记录。 官方文档:https://techcommunity.microsoft.com/blog/azurecompute/azure-functions-support-for-http-streams-in-python-is-now-in-prev…...

智能座舱进阶-应用框架层-Jetpack主要组件
Jetpack的分类 1. DataBinding:以声明方式将可观察数据绑定到界面元素,通常和ViewModel配合使用。 2. Lifecycle:用于管理Activity和Fragment的生命周期,可帮助开发者生成更易于维护的轻量级代码。 3. LiveData: 在底层数据库更…...
GitLab分支管理策略和最佳实践
分支管理是 Git 和 GitLab 中非常重要的部分,合理的分支管理可以帮助团队更高效地协作和开发。以下是一些细化的分支管理策略和最佳实践: 1. 分支命名规范 • 主分支:通常命名为 main 或 master,用于存放稳定版本的代码。 • …...
【Unity】【VR开发】实现VR屏幕共享应用的几个重要插件和参考资料分享
【背景】 做了一个可以在局域网远程屏幕的VR应用,如果有相同兴趣的朋友也可以参考下我用的几个插件。 【使用或相关的关键插件】 piping server:这个是最基底的插件,基于它实现的信令通信。 https://github.com/nwtgck/piping-server/blob…...

数据结构---------二叉树前序遍历中序遍历后序遍历
以下是用C语言实现二叉树的前序遍历、中序遍历和后序遍历的代码示例,包括递归和非递归(借助栈实现)两种方式: 1. 二叉树节点结构体定义 #include <stdio.h> #include <stdlib.h>// 二叉树节点结构体 typedef struct…...

浏览器引入elasticsearch-head插件
elasticsearch-head插件下载: 链接: https://pan.baidu.com/s/1Dz3aU42HZCNg45iJoDOsMg?pwduvhg 提取码: uvhg 1、打开浏览器设置 2、选择拓展程序 3、选择elasticsearch-head插件下载 4、打开es-head插件 5、修改ip 6、登录...

【ELK】Filebeat采集Docker容器日志
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 介绍filebeat是如何工作的 使用部署filebeat 介绍 Filebeat 是一个用于转发和集中日志数据的轻量级传送器。 Filebeat 作为agent安装在服务器上,监视指…...

异步线程池与CountDownLatch
异步线程池 顾名思义,一个专门用来处理异步任务的线程池。可以避免线程的开销以及非阻塞的执行任务。 CountDownLatch 一个同步工具类,用于 让一个或多个线程等待一组操作完成。 业务场景 支付订单时,用户可以使用多张优惠劵,…...
在图像上显示掩码、框和点的通用函数
在图像上显示掩码、框和点的通用函数 背景介绍函数实现与用途1. 显示掩码函数:`show_mask`2. 显示边界框函数:`show_box`3. 在图像上显示点函数:`show_points`4. 综合显示框和点函数:`show_points_and_boxes_on_image`5. 显示掩码并返回图像函数:`show_mask_on_image`6. 显…...
基于Matlab的变压器仿真模型建模方法(11):三相三绕组换流变压器的建模仿真
1.概述 换流变压器是直流输电系统中的关键设备,主要负责连接交流和直流系统,并实现电能的转换与传输。换流变压器在直流输电系统中的主要用途包括:传送电力:将电能从交流系统传输到直流系统或从直流系统传输到交流系统;电压变换:把交流系统电压变换到换流器所需的换相电压…...
代码随想录算法训练营day46|动态规划part12
今天就结束动态规划章节了,以后还要多加练习。 今天的两道题都很有难度,647回文子串的思路非常巧妙,因为用一维dp数组比较难表示子串的起点和终点,所以需要用二维dp数组表示,dp[i][j]表示以i为起点,j为终点…...

【C语言】头文件
所有学习过C语言的朋友都熟悉这样一段代码: #include <stdio.h>int main(int argc, char *argv[]) {return 0; }那么,你真的了解 <stdio.h> 吗? <stdio…...

蓝桥杯——竞赛省赛国赛题分享
目录 一.[蓝桥杯 2013 省 AB] 错误票据 代码如下: 二.[蓝桥杯 2024 省 Java B] 报数游戏 代码如下: 讲解: 三.[蓝桥杯 2014 国 C] 拼接平方数 代码如下: 四.三步问题(递归,上台阶) 代码…...

企业内训|阅读行业产品运营实战训练营-某运营商数字娱乐公司
近日,TsingtaoAI公司为某运营商旗下数字娱乐公司组织的“阅读行业产品运营实战训练营”在杭州落下帷幕。此次训练营由TsingtaoAI资深互联网产品专家程靖主持。该公司的业务骨干——来自内容、市场、业务、产品与技术等跨部门核心岗位、拥有8-10年实战经验的中坚力量…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...