【PHP】控制摄像头缩放监控画面大小,并保存可视画面为图片

一、前言

功能描述

调用摄像头并可以控制缩放摄像头监控画面的大小,把可视画面保存为图片。

我使用的是USB摄像头,其他摄像头此方法应该也通用。

使用技术

使用到的技术比较简单,前端使用WebcamJS插件调用摄像头,并摄像头监控画面,使用CSS的transform属性来放大或缩小画面的大小。后端使用PHP的Imagick类库来缩放图片,最终保存图片到本地。

二、最终效果

Capture:保存可视区域图片;放大:放大可视区域画面;缩小:缩小可视区域画面;还原:还原可视区域画面。

三、业务逻辑说明

前端

① 调用摄像头:使用WebcamJS库调用摄像头,显示监控画面(注意:需要在https下才能使用此插件);

② 缩放画面:先初始可视区域的宽高,设置scale缩放比例,再使用CSS的transform属性来缩放画面大小(注意:transform属性只是在视觉上对图片进行了缩放,其实和图像的真实大小并不一致,因为我这里为了保持放大后的图像尺寸大小和原始图像尺寸大小在视觉上一致,所以我把多余的画面区域使用overflow隐藏了);

③ 数据传输后端:把图片数据和缩放比例传输给PHP后端进行处理。此时传输的图像数据是base64编码,尺寸大小并不是视觉上所看到的画面大小,这个需要在后端进行处理。

后端

① 接收前端传过来的数据(base64图片编码、缩放比例);

② 把接收的base64编码保存为图片到本地;

③ 对图片进行处理:使用Imagick类库对图像进行处理,前面说了前端传过来的图像尺寸并不是可视区域的尺寸,所以为了保存一致,需要对接收的原始图像进行缩放处理。需要两个步骤,先是根据放大比例计算并保存放大后的图片(是原始大小的图片,不是视觉大小的图片),再对该图片进行裁剪,裁剪方法是计算裁剪区域的起始坐标,这个坐标是从放大后图像的中心位置开始计算的,最后根据这个坐标和裁剪尺寸进行裁剪并保存新的图片。这样就得到了一个从放大后的图像中心为圆心,向外扩散裁剪;

④ 保存裁剪后的图片,进行后续操作。

四、代码

前端

<!doctype html><html lang="en">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>WebcamJS Test Page - Large Capture</title><style type="text/css">body { font-family: Helvetica, sans-serif; }h2, h3 { margin-top:0; }form { margin-top: 15px; }form > input { margin-right: 15px; }#my_camera {  transition: transform 0.3s ease-in-out; /* 添加过渡效果,使变换更平滑 */  transform-origin: center center; /* 变换原点设置为图片中心 */  width: 100%; /* 初始尺寸设置为容器宽度 */  height: auto; /* 保持图片的宽高比 */  }#imageContainer{width: 640px; /* 设置你想要的容器宽度 */  height: 480px; /* 设置你想要的容器高度 */  overflow: hidden; /* 隐藏超出容器的部分 */  position: relative; /* 如果需要相对于容器定位图片,可以添加这个属性 */}</style>
</head>
<body><h1>WebcamJS Test Page - Large/Small Capture</h1><div id="imageContainer" style=""><div id="my_camera"></div></div><!-- A button for taking snaps --><form><input type=button value="Capture" onClick="take_snapshot()"><input type=button value="放大" id="zoomIn" ><input type=button value="缩小" id="zoomOut"><input type=button value="还原" id="reset"></form><script type="text/javascript" src="/static/index/js/webcam.min.js"></script><script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script><script language="JavaScript">Webcam.set({width: 640,height: 480,image_format: 'jpeg',jpeg_quality: 90});Webcam.attach( '#my_camera' );</script><script language="JavaScript">function take_snapshot() {// take snapshot and get image dataWebcam.snap( function(data_uri) {console.log(scale)var imgBase64 = data_uri$.ajax({url:'/index/camera/photo',dataType:'JSON',type:'POST',data:{data:imgBase64,scale:scale},success:function (res) {console.log(res)}})});}var scale = 1; // 初始缩放比例  $('#zoomIn').click(function() {  if (scale < 3) { // 限制最大缩放比例,这里设置为3 scale += 0.1; // 每次点击放大0.1  $('#my_camera').css('transform', 'scale(' + scale + ')');  }  // 计算放大后的尺寸var originalWidth = $("#my_camera").width();var originalHeight = $("#my_camera").height();var zoomedWidth = originalWidth * scale;  var zoomedHeight = originalHeight * scale; console.log(zoomedWidth)console.log(zoomedHeight)});  $('#zoomOut').click(function() {  if (scale > 1) { // 限制最小缩放比例,这里设置为1  scale -= 0.1; // 每次点击缩小0.1  $('#my_camera').css('transform', 'scale(' + scale + ')'); }  });  $('#reset').click(function() {  scale = 1$('#my_camera').css('transform', 'scale(' + scale + ')'); });  </script></body>
</html>

后端

// 处理图像
public function photo()
{$image= input('post.data');		//接收base64数据$scale= input('post.scale');	//接收缩放比例//图片存放的路径$path = "uploads".DS."chufang".DS.date('Y-m-d', time()) . DS;// 检查该目录是否存在,不存在就创建if (!file_exists($path)) {mkdir($path, 0700, true); //创建目录chmod($path, 0700); //赋予权限}$uid = session('uid');//确保图片名唯一,防止重名产生覆盖$imageName = 'wx_' .$uid.'_'. time() . rand(1000, 9000) . '.jpg';//判断是否有逗号 如果有就截取后半部分if (strstr($image,",")){$image = explode(',',$image);$image = $image[1];}//图片完整路径$imageSrc= ROOT_PATH .'public' .DS. $path . $imageName;// 生成文件夹和图片$r = file_put_contents($imageSrc, base64_decode($image));// 原始图像路径$sourceImagePath= $imageSrc;// 目标图像路径$targetImagePath = ROOT_PATH .'public' .DS. $path .'target.jpg';  // 实例化(原始图像路径)$image = new \Imagick($sourceImagePath);// 获取原始图像的尺寸  $originalWidth = $image->getImageWidth();  $originalHeight = $image->getImageHeight();  // 计算放大后图像的尺寸(这仅用于计算裁剪区域,最终图像尺寸保持不变)  $scaledWidth = $originalWidth * $scale;$scaledHeight = $originalHeight * $scale;// 保存放大后的图像  $image->resizeImage($scaledWidth, $scaledHeight, \Imagick::FILTER_LANCZOS, 1);  // 设定裁剪区域的尺寸(这里设置与原始图像一样大的尺寸)  $cropWidth = $originalWidth * 1; 	// 如果比原始宽度大50%,可*1.5  $cropHeight = $originalHeight * 1; // 如果比原始高度大50%,可*1.5 // 计算裁剪区域的起始坐标(从放大后图像的中心开始)  $startX = ($scaledWidth - $originalWidth) / 2;  $startY = ($scaledHeight - $cropHeight) / 2;  // 确保起始坐标是整数(因为像素坐标必须是整数)  $startX = (int)round($startX);  $startY = (int)round($startY);  // 使用 Imagick 的 cropImage 方法裁剪图像  $image->cropImage($cropWidth, $cropHeight, $startX, $startY);  // 保存新图像$image->writeImage($targetImagePath);  // 清除资源  $image->clear();  $image->destroy();  }

 五、资源下载

WebcamJS: jQuery移动端调用摄像头拍照插件WebcamJS

Imagick:PHP安装Imagick扩展库(网上有教程,可自行搜索)

完整代码下载:https://download.csdn.net/download/qq_25285531/89487658

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

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

相关文章

《mysql》--mysql约束

数据库约束 有的时候数据库中的数据是有一定要求的&#xff0c;有些数据认为是合法数据&#xff0c;有些是非法数据&#xff0c;如果靠人工检查显然是不靠谱的&#xff1b; 数据库会自动的对数据的合法性进行校验检查目的就是&#xff0c;保证数据中能够避免被插入/修改一些非…

Linux基础 - 使用 ssh 服务管理远程主机(window linux vscode)

目录 零. 简介 一. 打开linux shh 二. window连接linux 三. linux连接linux 四. VSCode远程 零. 简介 SSH&#xff08;Secure Shell&#xff09;服务是一种网络协议&#xff0c;主要用于在不安全的网络环境中为计算机之间的通信提供安全的加密连接。 SSH 服务具有以下重要…

二、安装虚拟机

本篇来源&#xff1a;山海同行 本篇地址&#xff1a;https://shanhaigo.cn/courseDetail/1805875642621952000 本篇资源&#xff1a;以整理到-山海同行 一、官网下载centos7 1. 进入CentOS 官方网站 官方网站&#xff1a;https://www.centos.org/download/ 2. 选择iso 点击下…

高中数学:不等式-常用不等式知识点汇总

一、基本性质 比较大小的常用两种方法&#xff1a;作差法&#xff0c;作商法 等式性质 不等式性质 二、基本(均值)不等式 扩展 三、二次函数与一元二次方程不等式 定义 解的对应关系 一元二次不等式的求解过程 四、二元一次不等式(组)与线性规划 关键在于求多个不等…

无线领夹麦克风怎么挑选,能让声音变好听的领夹麦推荐大全

近年来&#xff0c;随着直播销售和个人视频日志&#xff08;Vlog&#xff09;的流行&#xff0c;自媒体内容创作已经成为一种文化现象。这一现象不仅改变了人们获取信息的方式&#xff0c;也极大地推动了相关音频设备的发展。无线领夹麦克风&#xff0c;以其轻巧的设计和出色的…

MySQL数据库基础练习系列:科研项目管理系统

DDL CREATE TABLE Users (user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID,username VARCHAR(50) NOT NULL UNIQUE COMMENT 用户名,password VARCHAR(255) NOT NULL COMMENT 密码,gender ENUM(男, 女) NOT NULL COMMENT 性别,email VARCHAR(100) UNIQUE COMMENT 邮箱 …

字节码编程ASM之idea插件asm bytecode outline的使用

写在前面 直接用ASM来编写字节码程序难度其实还是蛮大的&#xff0c;为此&#xff0c;就有热心人事开发了相关的idea插件 &#xff0c;其中比较优秀的一个是asm bytecode outline,本文就来一起看下如何使用。 1&#xff1a;安装 file->setting->plugins,搜索asm bytec…

gin-vue-amdin 新增路由

1&#xff1a;在api目录的example 下新建controller 层如下图&#xff08;&#xff09;&#xff1a; 在enter.go 中 加入 这个新建的结构体&#xff1a; 2&#xff1a;在router 的example 文件夹下 新建对应的路由文件 3&#xff1a;在initlize 的router 中 添加对应的代码&a…

PDF处理篇:有哪些免费的PDF注释工具

PDF 是一种功能强大的格式&#xff0c;广泛用于处理和传输数据。您可以创建自己的 PDF 文件&#xff0c;也可以使用其他人创建的 PDF 文件。但是&#xff0c;有时您想在 PDF 文件中包含其他文本、图形和其他元素。这就是 PDF 注释器为您提供帮助的地方。 有许多可用的 PDF 注释…

无线领夹麦克风品牌排名,揭秘哪种领夹麦性价比高!

在直播电商和Vlog的热潮推动下&#xff0c;自媒体内容创作迎来了前所未有的繁荣。麦克风行业也因应这一趋势&#xff0c;迎来了快速的增长期。特别是无线领夹麦克风&#xff0c;以其便携性和高效的录音能力&#xff0c;迅速成为视频制作者的新宠。它不仅在直播带货和短视频制作…

allure安装教程

1、下载 allure的官网下载地址&#xff1a; https://github.com/allure-framework/allure2/releases 注意&#xff1a;官网时常访问失败&#xff0c;可以访问以下网址&#xff1a; https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/ 选择一个版本&…

Uniapp的使用

为什么要使用uniapp uniapp 可以进行多端开发&#xff0c;uniapp 在设计的时候就拥有许多兼容性代码&#xff0c;可以兼容很多的平台 如 支付宝小程序 html页面 微信小程序等&#xff0c;注重开发效率而不是运行效率时 &#xff0c;就可以考虑一下 uniapp 当然也可以去…

ABAP ALV报表性能优化 经验总结

优化ALV报表&#xff0c;最主要就是优化取数逻辑和数据库查询。因为几乎在所有的程序中都会用到数据库查询&#xff0c;所以这篇文章的内容也不仅局限于SAP、ABAP程序&#xff0c;虽然ABAP有其特殊之处。 优化的时候我遵从以下几个原则&#xff1a; 1.把数据库连接视为一种极其…

Vivo手机怎么录屏?分享2种录屏方法

“新换的Vivo手机还挺好用的&#xff0c;但是今天看到一个视频想录下来保存&#xff0c;但找不到录屏功能啊&#xff0c;想问问大家Vivo手机的录屏功能怎么打开啊&#xff1f;还有Vivo手机能不能录制出高质量的视频呢&#xff1f;” 随着智能手机的普及&#xff0c;录屏功能已…

ChatTTS源码部署

感谢阅读 默认已完成的操作准备工作下载源码安装依赖下载补丁(报错在运行) 界面展示(discord上有各种补丁&#xff0c;我的加了UI补丁和音色增强)提示词常用&#xff08;这个每个音基本都能生效&#xff09;语调类语速类情感类 默认已完成的操作 python版本>3.9 cuda版本的…

《化工管理》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《化工管理》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第一批认定学术期刊。 问&#xff1a;《化工管理》级别&#xff1f; 答&#xff1a;国家级。主办单位&#xff1a;中国石油和化学工业联合会 主管单位&…

国产操作系统上配置ssh互信 _ 统信 _ 麒麟 _ 中科方德

原文链接&#xff1a;国产操作系统上配置ssh互信 | 统信 | 麒麟 | 中科方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇在国产桌面操作系统上配置SSH互信的文章。SSH&#xff08;Secure Shell&#xff09;是一种安全协议&#xff0c;用于在不安全的网络上安全地…

uniapp app分享页面到微信的功能方法

最近开发uniapp app项目时&#xff0c;有分享页面的功能需求&#xff0c;因此&#xff0c;给大家分享一下&#xff0c;在uniapp环境里&#xff0c;是如何分享页面到微信H5页面的。 如上图所示&#xff1a;app主体代码就是这样了&#xff0c;查看相应配置就可以&#xff0c;同时…

Swoole v6 能否让 PHP 再次伟大?

大家好&#xff0c;我是码农先森。 现状 传统的 PHP-FPM 也是多进程模型的的运行方式&#xff0c;但每个进程只能处理完当前请求&#xff0c;才能接收下一个请求。而且对于 PHP 脚本来说&#xff0c;只是接收请求和响应请求&#xff0c;并不参与网络通信。对数据库资源的操作…

Android (已解决)Execution failed for task ‘:app:lint‘

文章目录 一、错误原因二、解决方法 一、错误原因 这个错误信息表示在执行 Lint 检查时发现了错误&#xff0c;导致构建过程被中断。Lint 是一个用于检测 Android 项目中潜在问题的工具&#xff0c;比如性能、安全性、可用性等方面的问题。当Lint检查到严重错误时&#xff0c;…