一直以来,在网页上直接拍照片,通过几行代码就可以调动硬件摄像头是不可能实现的,而HTML5却把这个梦想般的功能变成了现实。
1.在Web中拍照示例
本例中,我们使用HTML5里的getUserMedia来演示在Web中进行拍摄的功能,如下图:
本例代码如下所示:
<html lang = “ zh-cn” manifest = “ index.manifest” xmlns = “ http://www.w3.org/1999/xhtml” > <head> <title>网页拍照功能</ title> <meta charset = “ UTF-8” /> <元名称= “视口” content = “宽度=设备宽度,高度=设备高度,初始比例= 1.0,最小比例= 1.0,最大比例= 1.0,用户-可伸缩=否,target-densityDpi =设备dpi“ /> <link href = ” operacamera.css“ rel = ”样式表“type = “ text / css” />
<style type = “ text / css” > / * < ![CDATA [* / body {background-image:url('opera_camera_bg.png' ); } / *]] > * / </ style> <script type = “ text / javascript” charset = “ utf-8” src = “ foropera.js” > </ script> </ head> <body> <div id = “ helpme”样式=
“不透明度:0.9;位置:绝对; z-index:1000;顶部:100px;左侧:20px;显示:无;背景色:#333; -webkit-border-radius:15px;右侧:20px;” > <center style = “ margin-left:10px; margin-right:10px; border-bottom:1px#777 solid;” > <span style = “ color:#fff; height:30px; line-height:60px; font-size:26px;” >拍照功能</ span> </ center> <div style = “ color:#ccc; font-size:18px; margin-left:20px; margin-right:20px; margin-top:16px;” >
/> <center> <button onclick = “ hiddeDiv('helpme')” style = “ opacity:1; background-color:#777; border:0px; height:35px; line-height:25px; color:#eee;宽度:140像素;字体大小:18像素; -webkit-border-radius:5像素;” >关闭提示</ button> </ center> <br /> </ div> <div id = “ help” style = “ z-index:1000; position:absolute; left:0px; top:30px;” > </ div> <script type = “ text / javascript” > // < !
)。样式.display = 'none' ;
}
函数showhelp(){
document.getElementById('helpme' )。样式.display = '' ;
}
// ]] > </ script> <div id = “ container” > <div id = “ subcontainer” > <div id = “ piclist” > </ div> <div id = “ left” > </ div> <div id = “ right” >
“ picbutton” > <h2 id = “ click” >拍照</ h2> <div id = “ status” style = “ display:none;” > </ div> </ div> </ div> </ div> <div id = “ footer” > <div id = “ pictures” > </ div> </ div> </ div> <div id = “ msg“ style = ” display:none; width:300px; height:200px; z-index:900; font-size:14px; color:#000; text-align:
= “ btn” onclick = “ copyimgtoserver()” >保存此图片</a> <br /> <br /> <a class = “ btn” onclick = “ deleteImg();” >放弃此图片</a> </ div> <div id = “ tempimg” style = “ display:none; position:absolute; top:150px; left:30px; text-align:center;” > <img id = “ displayimg”宽度= “ 400”高度= “ 400”
onclick = “ $('tempimg')。style.display ='none';” >关闭</ button> </ div> <脚本类型= “ text / javascript” > // < ![CDATA [ //先判断这人有没有用过照相机,如果用过,就写下一个ID if( localStorage.cameraid_opera == null){ var temp_id = new Date()。getTime(); localStorage.cameraid_opera = temp_id; //建立用户的身份识别 } var cam_mem = localStorage.cameraMemory; if(cam_mem!= null){ var temp_arr = cam_mem.split(“ |” ); } else { var temp_arr = []; } for(var iii = 1; iii <
temp_arr.length; 3 ++){
// 。读出存储在本地的相片这类似一个本地相册,在实际案例中是注释掉未予执行的
//在此处帖出全部代码供读者参考
//变种img = document.createElement('img' );
// img.src = temp_arr [iii];
// img.id = temp_arr [iii];
// img.addEventListener('click' ,displayImg,true);
// img.width = “ 40” ;
// img.height = “ 40” ;
// $('piclist' ).appendChild(img);
}
var button = document.querySelector('#picbutton' );
button.addEventListener('click' ,
window.addEventListener('devicemotion' ,reset,false);
localStorage.lastcanvasid = 0;
var prev = 0;
var video_element = document.querySelector('video' );
if(navigator.getUserMedia){
navigator.getUserMedia('video' ,v_success,v_error);
}否则if(opera.getUserMedia){
Opera.getUserMedia('video' ,v_success,v_error);
}其他{
not_supported();
}
函数not_supported(){
var message = document.querySelector('#message' );
message.innerHTML = “ <h1>此浏览器不支持读取摄像头<\ / h1>” ;
函数v_success(stream){
video_element.src = stream;
//注意,此处视频的宽高尺寸应该照以下代码读取
// alert(video_element.clientWidth + “,” + video_element.clientHeight)
}
函数v_error(error){
opera.postError(“错误!错误码为: “ + error.code);
}
function snapshot(){ //拍摄函数
var canvas = document.createElement('canvas' );
var vw = video_element.clientWidth;
var vh = video_element.clientHeight;
var vvw = video_element.videoWidth;
var vvh = video_element.videoHeight;
canvas.width = vw;
canvas.height = vh;
video_element.width = vw;
video_element.height = vh;
canvas.className = “ pic” ;
var _a = new Date()。getTime();
canvas.id = localStorage.cameraid_opera + “ canvas” + _a; //生成照片的ID
var deg = getDeg();
canvas.style.OTransform = “ rotate(” + deg + “ deg)” ;
canvas.style.MozTransform = “ rotate(” + deg + “ deg)” ;
canvas.style.webkitTransform = “ rotate(” + deg + “ deg)” ;
canvas.style.msTransform = “ rotate(” + deg + “
var footer = document.querySelector(“ #pictures” );
if(localStorage.lastcanvasid == 0){
footer.appendChild(canvas);
localStorage.lastcanvasid = localStorage.cameraid_opera + “ canvas” + _a;
} else {
footer.insertBefore(canvas,$(localStorage.lastcanvasid));;
localStorage.lastcanvasid = localStorage.cameraid_opera + “ canvas” + _a;
}
var c = canvas;
var ctx = c.getContext('2d' );
var cw = vw;
var ch = vh;
ctx.fillStyle = “ #fff ” ;
ctx.fillRect(0,0,cw,ch);
ctx.drawImage(video_element,0,0,vvw,vvh,0,0,vw,
applyEvents();
}
函数applyEvents(){ //事件绑定函数
var elems = document.querySelectorAll('canvas' );
for(var i = 0; i < elems.length; i ++){
// elems [ i ] .addEventListener('click' ,msgbox,true);
//给每张照片赋于点击事件,例如可放大可缩小
//在真实案例中我们注释掉了此功能,在本处标出以供读者参考
}
}
function msgbox(){ //布局函数
$('msg' )。样式.display = '' ;
$('msg' )。样式.position ='绝对' ;
$('msg' )。样式.top =((window.innerHeight / 2 )-100)+ “ px” ;
$('msg' )。样式.left =((window.innerWidth / 2 )-150)+ “ px” ;
localStorage.xxxxid =此。id ;
}
函数newimg(){
var datauri = this.toDataURL(“ image / png” );
window.open(datauri);
}
函数 reset (){
var acc_x = topos(event .acceleration.x);
变种 acc_y = topos(event .acceleration.y);
var acc_z = topos(event .acceleration.z);
if((acc_x || acc_y || acc_z)> 15.5){
var canvass = document.querySelectorAll('canvas' );
var polaroid = document.querySelector('#pictures' );
for(var i = 0; i < canvases.length; i ++){
polaroid.removeChild(canvases [i]);
}
}
}
function getDeg(){ //角度生成函数
if(prev == 0){
var number = Math.floor(Math.random()* 45);
上一页+ = 1;
返回编号;
} 别的{
var number = Math.floor(Math.random()* 45);
数字* = -1;
上一页-= 1;
返回编号;
}
}
函数topos(num){
if(num < 0 ){ num * =-1; } return num; } 函数copyimgtoserver(){ $('msg' )。样式.display = “ none” ; var c = $(localStorage.xxxxid); var myImage = c.toDataURL(“ image / png” ); //如果在上一步得不到数据,是因为安全问题。//请在地址栏中输入歌剧:配置,选择安全性偏好设置,勾选使相机 帆布 复制
//即可,大概5-17
var str = “” pic_data =“ + myImage;
//下面是将拍摄的照片传送到服务器中的代码,是网络相册的核心步骤之一
var request = new Xhr('POST' , 'server_getpic.php?rnd =' + Math.random(),true, STR,
功能(数据){
//把名字存到的localStorage中
localStorage.cameraMemory = localStorage.cameraMemory + “|” +数据。文本;
VAR IMG =使用document.createElement('IMG' ); IMG 。SRC =数据。文本; img 。
id =数据。文字;
// img .addEventListener('click' ,displayImg,true);
img 。宽度= “ 40” ;
img 。高度= “ 40” ;
$('piclist' )。appendChild(img );
c.parentNode.removeChild(c);
$('状态' )。样式.display = “ none” ;
});
//传上去以后,关闭层,把图片显示在某个位置
}
函数displayImg(){
$('displayimg' )。src=这个。id
$('tempimg' )。样式.display = '' ;
}
函数deleteImg(){
var c = $(localStorage.xxxxid);
c.parentNode.removeChild(c);
$('msg' )。样式.display = “ none” ;
}
// ]] > </ script> </ body> </ html>
2.本例小结
本例在网页上实现拍摄,代码极其简单。在这个例子中,我们本来做得较多复杂,但是演示时将一些代码注释掉了,从而将拍到的照片写入画布,然后从画布中再获得数据传输到网络中(当网络不通顺的时候,临时存在本地),轻松变成了一个网络相册。
但是,这里有一个极为重要的Canvas安全问题。Canvas与摄像头在定义上是两个不同的数据源,不同的域,因此,不能直接去本地Canvas的数据。
在实际的域的概念中,以前我们所熟悉的A域不等于B域,这两个域往往是指两个不同的站点。而在这个示例中,可能会有3个概念:摄像头设备是一个独立的域,本机的Canvas是一个域,远程的网站是一个域。
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h61367.shtml