js调用本地摄像头拍照截图,提交后台

古城微笑少年丶 2022-05-15 07:53 553阅读 0赞

今天有个需求,需要在前端界面调用本地摄像头,然后拍照结束后可以截取预览,最后将结果提交到后台。查了网上很多的插件,发现适合的非常少,于是决定自己修改一个。

这里我修改了一个jquery插件,把摄像头拍照的功能融合了进去。

提交到后台时是提交一个base64字符,在后台再将base64字符转换为图片保存。

效果图:

70

支持本地上传,下载完整demo可以直接运行。

demo 的git下载地址:https://github.com/HL-Guitar/photograph

getUserMedia函数是请求用户摄像头的方法,随着浏览器版本的更新可能无法兼容,可以修改这个方法来实现兼容,最新版本火狐,旧版本谷歌没有问题。

完整demo:

  1. <button id="replaceImg" class="l-btn">更换图片</button>
  2. <!--图片裁剪框 start-->
  3. <div style="display: none" class="tailoring-container">
  4. <div class="black-cloth" onclick="closeTailor(this)"></div>
  5. <div class="tailoring-content">
  6. <div class="tailoring-content-one">
  7. <label title="上传图片" for="chooseImg" class="l2-btn choose-btn">
  8. <input type="file" accept="image/jpg,image/jpeg,image/png" name="file" id="chooseImg" class="hidden" onchange="selectImg(this)">
  9. 本地上传
  10. </label>
  11. <label title="拍照" class="l2-btn choose-btn" id='capture' style="margin-left: 2%;">拍照</label>
  12. <label title="重拍" class="l2-btn choose-btn" id='takeAgain' style="margin-left: 2%;">重拍</label>
  13. <div class="close-tailoring" onclick="closeTailor(this)">×</div>
  14. </div>
  15. <div class="tailoring-content-two">
  16. <div class="tailoring-box-parcel">
  17. <video id="video" width="100%" height="100%" controls style="float: left;" ></video>
  18. <canvas id="canvas" width="482px" height="448px" style="float: left;" hidden="hidden"></canvas>
  19. <div id="showImg" hidden="hidden" style="width: 100%;height:100%;">
  20. <img id="tailoringImg">
  21. </div>
  22. </div>
  23. <div class="preview-box-parcel">
  24. <p>图片预览:</p>
  25. <div class="square previewImg"></div>
  26. <div class="circular previewImg"></div>
  27. </div>
  28. </div>
  29. <div class="tailoring-content-three">
  30. <button class="l2-btn cropper-reset-btn">复位</button>
  31. <button class="l2-btn cropper-rotate-btn">旋转</button>
  32. <button class="l2-btn cropper-scaleX-btn">换向</button>
  33. <button class="l2-btn sureCut" id="sureCut">确定</button>
  34. </div>
  35. </div>
  36. </div>
  37. <!--图片裁剪框 end-->
  38. <script>
  39. //弹出框水平垂直居中
  40. (window.onresize = function () {
  41. var win_height = $(window).height();
  42. var win_width = $(window).width();
  43. if (win_width <= 768){
  44. $(".tailoring-content").css({
  45. "top": (win_height - $(".tailoring-content").outerHeight())/2,
  46. "left": 0
  47. });
  48. }else{
  49. $(".tailoring-content").css({
  50. "top": (win_height - $(".tailoring-content").outerHeight())/2,
  51. "left": (win_width - $(".tailoring-content").outerWidth())/2
  52. });
  53. }
  54. })();
  55. //图像上传
  56. function selectImg(file) {
  57. if (!file.files || !file.files[0]){
  58. return;
  59. }
  60. var reader = new FileReader();
  61. reader.onload = function (evt) {
  62. var replaceSrc = evt.target.result;
  63. //更换cropper的图片
  64. $('#tailoringImg').cropper('replace', replaceSrc,false);//默认false,适应高度,不失真
  65. }
  66. reader.readAsDataURL(file.files[0]);
  67. mediaStreamTrack && mediaStreamTrack.stop();
  68. $("#video").hide();
  69. $("#showImg").show();
  70. }
  71. //cropper图片裁剪
  72. $('#tailoringImg').cropper({
  73. aspectRatio: 1/1,//默认比例
  74. preview: '.previewImg',//预览视图
  75. guides: false, //裁剪框的虚线(九宫格)
  76. autoCropArea: 0.5, //0-1之间的数值,定义自动剪裁区域的大小,默认0.8
  77. movable: false, //是否允许移动图片
  78. dragCrop: true, //是否允许移除当前的剪裁框,并通过拖动来新建一个剪裁框区域
  79. movable: true, //是否允许移动剪裁框
  80. resizable: true, //是否允许改变裁剪框的大小
  81. zoomable: false, //是否允许缩放图片大小
  82. mouseWheelZoom: false, //是否允许通过鼠标滚轮来缩放图片
  83. touchDragZoom: true, //是否允许通过触摸移动来缩放图片
  84. rotatable: true, //是否允许旋转图片
  85. crop: function(e) {
  86. // 输出结果数据裁剪图像。
  87. }
  88. });
  89. //弹框
  90. $("#replaceImg").on("click",function () {
  91. takeImg()
  92. });
  93. //旋转
  94. $(".cropper-rotate-btn").on("click",function () {
  95. $('#tailoringImg').cropper("rotate", 45);
  96. });
  97. //复位
  98. $(".cropper-reset-btn").on("click",function () {
  99. $('#tailoringImg').cropper("reset");
  100. });
  101. //换向
  102. var flagX = true;
  103. $(".cropper-scaleX-btn").on("click",function () {
  104. if(flagX){
  105. $('#tailoringImg').cropper("scaleX", -1);
  106. flagX = false;
  107. }else{
  108. $('#tailoringImg').cropper("scaleX", 1);
  109. flagX = true;
  110. }
  111. flagX != flagX;
  112. });
  113. //裁剪后的处理
  114. $("#sureCut").on("click",function () {
  115. var cas = $('#tailoringImg').cropper('getCroppedCanvas');//获取被裁剪后的canvas
  116. var base64url = cas.toDataURL('image/png'); //转换为base64地址形式
  117. base64url=base64url.replace("\r","")
  118. $.post("../Info", {op:"takePhoto",base64url:base64url }, function(data) {
  119. var result=parseInt($.trim(data.result));
  120. if(result==-1){
  121. $.messager.show({title:"温馨提示",msg:"输入的信息不完整,确认后重新提交。",timeout:3000,showType:'slide'})
  122. }else if(result>0){
  123. $.messager.show({title:"成功提示",msg:"头像更新成功",timeout:3000,showType:'slide'})
  124. //$('#attendance_info').css('color','green').text("已提交");
  125. }else{
  126. $.messager.alert("失败提示","头像更新失败,请稍后重试...",'error')
  127. }
  128. }, "JSON");
  129. //关闭裁剪框
  130. closeTailor();
  131. });
  132. //关闭裁剪框
  133. function closeTailor() {
  134. $(".tailoring-container").toggle();
  135. mediaStreamTrack && mediaStreamTrack.stop();
  136. }
  137. //访问用户媒体设备的兼容方法
  138. function getUserMedia(constraints, success, error) {
  139. if (navigator.mediaDevices.getUserMedia) {
  140. //最新的标准API
  141. navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
  142. } else if (navigator.webkitGetUserMedia) {
  143. //webkit核心浏览器
  144. navigator.webkitGetUserMedia(constraints,success, error)
  145. } else if (navigator.mozGetUserMedia) {
  146. //firfox浏览器
  147. navigator.mozGetUserMedia(constraints, success, error);
  148. } else if (navigator.getUserMedia) {
  149. //旧版API
  150. navigator.getUserMedia(constraints, success, error);
  151. }
  152. }
  153. let video = document.getElementById('video');
  154. let canvas = document.getElementById('canvas');
  155. let context = canvas.getContext('2d');
  156. var mediaStreamTrack
  157. function success(stream) {
  158. //兼容webkit核心浏览器
  159. let CompatibleURL = window.URL || window.webkitURL;
  160. //将视频流设置为video元素的源
  161. mediaStreamTrack = stream.getTracks()[0];
  162. //video.src = CompatibleURL.createObjectURL(stream);
  163. video.srcObject = stream;
  164. video.play();
  165. }
  166. function error(error) {
  167. alert('访问用户媒体设备失败,请尝试更换浏览器')
  168. }
  169. document.getElementById('capture').addEventListener('click', function () {
  170. context.drawImage(video, 0, 0, 480, 320);
  171. mediaStreamTrack && mediaStreamTrack.stop();
  172. $('#tailoringImg').cropper('replace', canvas.toDataURL("image/png"),false);//默认false,适应高度,不失真
  173. $("#video").hide();//隐藏拍照框
  174. $("#showImg").show()//将拍照结果显示
  175. })
  176. //请求拍照
  177. $("#takeAgain").bind("click", function(){
  178. takePhoto();
  179. });
  180. //开始拍照
  181. function takeImg(){
  182. $(".tailoring-container").toggle();
  183. takePhoto();
  184. }
  185. //请求摄像头
  186. function takePhoto() {
  187. if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
  188. //调用用户媒体设备, 访问摄像头
  189. getUserMedia({video : {width: 100, height: 100}}, success, error);
  190. $("#showImg").hide();//隐藏拍照结果显示框
  191. //$('#showImg').html('<img id="tailoringImg" hidden="hidden">')
  192. $("#video").show();//开启拍照框
  193. } else {
  194. alert('不支持访问用户媒体');
  195. }
  196. }
  197. </script>

发表评论

表情:
评论列表 (有 0 条评论,553人围观)

还没有评论,来说两句吧...

相关阅读