1、 视频流
HTML5 的 The Media Capture(媒体捕捉) API 提供了对摄像头的可编程访问,用户可以直接用 getUserMedia(请注意目前仅Chrome和Opera支持)获得摄像头提供的视频流。我们需要做的是添加一个HTML5 的 Video 标签,并将从摄像头获得的视频作为这个标签的输入来源。
<video id=”video” autoplay=”"></video>
<script>
var video_element=document.getElementById(‘video’)
if(navigator.getUserMedia){ // opera应使用opera.getUserMedianow
navigator.getUserMedia(‘video’,success,error)//success是回调函数,当然你也可以直接在此写一个匿名函数
}
function success(stream){
video_element.src=stream
}
</script>
此时,video 标签内将显示动态的摄像视频流。下面需要进行拍照了。
2、 拍照
拍照是采用HTML5的Canvas功能,实时捕获Video标签的内容,因为Video元素可以作为Canvas图像的输入,所以这一点很好实现。主要代码如下:
var canvas=document.createElement(‘canvas’)//动态创建画布对象
var ctx=canvas.getContext(’2d’)
var cw=vw,ch=vh
ctx.fillStyle=”#ffffff”
ctx.fillRect(0,0,cw,ch)
ctx.drawImage(video_element,0,0,cw,ch,0,0,vw,vh)//将video对象内指定的区域捕捉绘制到画布上指定的区域,可进行不等大不等位的绘制。
document.body.append(canvas)
3、 图片获取
从Canvas获取图片数据的核心思路是用canvas的toDataURL将Canvas的数据转换为base64位编码的PNG图像,类似于“data:image/pngbase64,xxxxx”的格式。
var imgData=canvas.toDataURL(“image/png”)
这样,imgData变量就存储了一长串的字符数据内容,表示的就是一个PNG图像的base64编码。因为真正的图像数据是base64编码逗号之后的部分,所以要让实际服务器接收的图像数据应该是这部分,我们可以用两种办法来获取。
第一种:是在前端截取22位以后的字符串作为图像数据,例如:
var data=imgData.substr(22)
如果要在上传前获取图片的大小,可以使用:
var length=atob(data).length//atob 可解码用base-64解码的字串
第二种:是在后端获取传输的数据后用后台语言截取22位以后的字符串(也就是在前台略过上面这步直接上传)。例如PHP里:
$image=base64_decode(str_replace(‘data:image/jpegbase64,’,”,$data)
4、 图片上传
在前端可以使用Ajax将上面获得的图片数据上传到后台脚本。例如使用jQuery时可以用:
$.post(‘upload.php’,{‘data’:data})
在后台我们用PHP脚本接收数据并存储为图片。
function convert_data($data){
$image=base64_decode(str_replace(‘data:image/jpegbase64,’,”,$data)
save_to_file($image)
}
function save_to_file($image){
$fp=fopen($filename,’w')
fwrite($fp,$image)
fclose($fp)
}
以上的解决方案不仅能用于Web App拍照上传,也可以通过Canvas的编辑功能函数提供图片编辑,例如裁剪、上色、涂鸦、圈点等功能,然后把用户编辑完的图片上传保存到服务器上。
在还在不断补充修正的HTML5的驱动下,Web App与Native App之间的距离将越来越小。在可预见的不远的未来,越来越多老的和新的开发项目必将会迁移到WEB应用上来。
相关规范:
(为便于阅读,对原文进行了不失原意的适当修改,包括代码中一些错误的重复,并作了注释)
HTML5技术支持WebApp在手机上拍照,显示在页面上并上传到服务器。这是手机微博应用中常见的功能,当然你也可以在其它类型应用中适当使用此技术。
1、 视频流
HTML5 的 The Media Capture(媒体捕捉) API 提供了对摄像头的可编程访问,用户可以直接用 getUserMedia(请注意目前仅Chrome和Opera支持)获得摄像头提供的视频流。我们需要做的是添加一个HTML5 的 Video 标签,并将从摄像头获得的视频作为这个标签的输入来源。
<video id=”video” autoplay=”"></video>
<script>
var video_element=document.getElementById(‘video’)
if(navigator.getUserMedia){ // opera应使用opera.getUserMedianow
navigator.getUserMedia(‘video’,success,error)//success是回调函数,当然你也可以直接在此写一个匿名函数
}
function success(stream){
video_element.src=stream
}
</script>
此时,video 标签内将显示动态的摄像视频流。下面需要进行拍照了。
2、 拍照
拍照是采用HTML5的Canvas功能,实时捕获Video标签的内容,因为Video元素可以作为Canvas图像的输入,所以这一点很好实现。主要代码如下:
var canvas=document.createElement(‘canvas’)//动态创建画布对象
var ctx=canvas.getContext(’2d’)
var cw=vw,ch=vh
ctx.fillStyle=”#ffffff”
ctx.fillRect(0,0,cw,ch)
ctx.drawImage(video_element,0,0,cw,ch,0,0,vw,vh)//将video对象内指定的区域捕捉绘制到画布上指定的区域,可进行不等大不等位的绘制。
document.body.append(canvas)
3、 图片获取
从Canvas获取图片数据的核心思路是用canvas的toDataURL将Canvas的数据转换为base64位编码的PNG图像,类似于“data:image/pngbase64,xxxxx”的格式。
var imgData=canvas.toDataURL(“image/png”)
这样,imgData变量就存储了一长串的字符数据内容,表示的就是一个PNG图像的base64编码。因为真正的图像数据是base64编码逗号之后的部分,所以要让实际服务器接收的图像数据应该是这部分,我们可以用两种办法来获取。
第一种:是在前端截取22位以后的字符串作为图像数据,例如:
var data=imgData.substr(22)
如果要在上传前获取图片的大小,可以使用:
var length=atob(data).length//atob 可解码用base-64解码的字串
第二种:是在后端获取传输的数据后用后台语言截取22位以后的字符串(也就是在前台略过上面这步直接上传)。例如PHP里:
$image=base64_decode(str_replace(‘data:image/jpegbase64,’,”,$data)
4、 图片上传
在前端可以使用Ajax将上面获得的图片数据上传到后台脚本。例如使用jQuery时可以用:
$.post(‘upload.php’,{‘data’:data})
在后台我们用PHP脚本接收数据并存储为图片。
function convert_data($data){
$image=base64_decode(str_replace(‘data:image/jpegbase64,’,”,$data)
save_to_file($image)
}
function save_to_file($image){
$fp=fopen($filename,’w')
fwrite($fp,$image)
fclose($fp)
}
以上的解决方案不仅能用于Web App拍照上传,也可以通过Canvas的编辑功能函数提供图片编辑,例如裁剪、上色、涂鸦、圈点等功能,然后把用户编辑完的图片上传保存到服务器上。
在还在不断补充修正的HTML5的驱动下,Web App与Native App之间的距离将越来越小。在可预见的不远的未来,越来越多老的和新的开发项目必将会迁移到WEB应用上来。
给你个图片处理的类吧,图片剪裁处理后,也就等于将图片压缩了。
/*** 图像处理类
* ============================================================================
* Copyright 2014 大秦科技,并保留所有权利。
* 网站地址: http://www.qintech.net;
* ============================================================================
*/
class Image{
//生成缩略图的方式
public $thumbType
//缩略图的宽度
public $thumbWidth
//缩略图的高度
public $thumbHeight
//生成缩略图文件名后缀
public $thumbEndFix
//缩略图文件前缀
public $thumbPreFix
/**
* 构造函数
*/
public function __construct(){
$this->thumbType = 1
$this->thumbWidth = 120
$this->thumbHeight = 60
$this->thumbPreFix =''
$this->thumbEndFix = '_thumb'
}
/**
* 检测是否为图像文件
* @param $img 图像
* @return bool
*/
private function check($img){
$type = array(".jpg", ".jpeg", ".png", ".gif")
$imgType = strtolower(strrchr($img, '.'))
return extension_loaded('gd') && file_exists($img) && in_array($imgType, $type)
}
/**
* 获得缩略图的尺寸信息
* @param $imgWidth 原图宽度
* @param $imgHeight 原图高度
* @param $thumbWidth 缩略图宽度
* @param $thumbHeight 缩略图的高度
* @param $thumbType 处理方式
* 1 固定宽度 高度自增 2固定高度 宽度自增 3固定宽度 高度裁切
* 4 固定高度 宽度裁切 5缩放最大边 原图不裁切
* @return mixed
*/
private function thumbSize($imgWidth, $imgHeight, $thumbWidth, $thumbHeight, $thumbType){
//初始化缩略图尺寸
$w = $thumbWidth
$h = $thumbHeight
//初始化原图尺寸
$cuthumbWidth = $imgWidth
$cuthumbHeight = $imgHeight
switch ($thumbType) {
case 1 :
//固定宽度 高度自增
$h = $thumbWidth / $imgWidth * $imgHeight
break
case 2 :
//固定高度 宽度自增
$w = $thumbHeight / $imgHeight * $imgWidth
break
case 3 :
//固定宽度 高度裁切
$cuthumbHeight = $imgWidth / $thumbWidth * $thumbHeight
break
case 4 :
//固定高度 宽度裁切
$cuthumbWidth = $imgHeight / $thumbHeight * $thumbWidth
break
case 5 :
//缩放最大边 原图不裁切
if (($imgWidth / $thumbWidth) > ($imgHeight / $thumbHeight)) {
$h = $thumbWidth / $imgWidth * $imgHeight
} elseif (($imgWidth / $thumbWidth) < ($imgHeight / $thumbHeight)) {
$w = $thumbHeight / $imgHeight * $imgWidth
} else {
$w = $thumbWidth
$h = $thumbHeight
}
break
default:
//缩略图尺寸不变,自动裁切图片
if (($imgHeight / $thumbHeight) < ($imgWidth / $thumbWidth)) {
$cuthumbWidth = $imgHeight / $thumbHeight * $thumbWidth
} elseif (($imgHeight / $thumbHeight) > ($imgWidth / $thumbWidth)) {
$cuthumbHeight = $imgWidth / $thumbWidth * $thumbHeight
}
// }
}
$arr [0] = $w
$arr [1] = $h
$arr [2] = $cuthumbWidth
$arr [3] = $cuthumbHeight
return $arr
}
/**
* 图片裁切处理
* @param $img 原图
* @param string $outFile 另存文件名
* @param string $thumbWidth 缩略图宽度
* @param string $thumbHeight 缩略图高度
* @param string $thumbType 裁切图片的方式
* 1 固定宽度 高度自增 2固定高度 宽度自增 3固定宽度 高度裁切
* 4 固定高度 宽度裁切 5缩放最大边 原图不裁切 6缩略图尺寸不变,自动裁切最大边
* @return bool|string
*/
public function thumb($img, $outFile = '', $thumbWidth = '', $thumbHeight = '', $thumbType = ''){
if (!$this->check($img)) {
return false
}
//基础配置
$thumbType = $thumbType ? $thumbType : $this->thumbType
$thumbWidth = $thumbWidth ? $thumbWidth : $this->thumbWidth
$thumbHeight = $thumbHeight ? $thumbHeight : $this->thumbHeight
//获得图像信息
$imgInfo = getimagesize($img)
$imgWidth = $imgInfo [0]
$imgHeight = $imgInfo [1]
$imgType = image_type_to_extension($imgInfo [2])
//获得相关尺寸
$thumb_size = $this->thumbSize($imgWidth, $imgHeight, $thumbWidth, $thumbHeight, $thumbType)
//原始图像资源
$func = "imagecreatefrom" . substr($imgType, 1)
$resImg = $func($img)
//缩略图的资源
if ($imgType == '.gif') {
$res_thumb = imagecreate($thumb_size [0], $thumb_size [1])
$color = imagecolorallocate($res_thumb, 255, 0, 0)
} else {
$res_thumb = imagecreatetruecolor($thumb_size [0], $thumb_size [1])
imagealphablending($res_thumb, false) //关闭混色
imagesavealpha($res_thumb, true) //储存透明通道
}
//绘制缩略图X
if (function_exists("imagecopyresampled")) {
imagecopyresampled($res_thumb, $resImg, 0, 0, 0, 0, $thumb_size [0], $thumb_size [1], $thumb_size [2], $thumb_size [3])
} else {
imagecopyresized($res_thumb, $resImg, 0, 0, 0, 0, $thumb_size [0], $thumb_size [1], $thumb_size [2], $thumb_size [3])
}
//处理透明色
if ($imgType == '.gif') {
imagecolortransparent($res_thumb, $color)
}
//配置输出文件名
$imgInfo = pathinfo($img)
$outFile = $outFile ? $outFile :dirname($img).'/'. $this->thumbPreFix . $imgInfo['filename'] . $this->thumbEndFix . "." . $imgInfo['extension']
Files::create(dirname($outFile))
$func = "image" . substr($imgType, 1)
$func($res_thumb, $outFile)
if (isset($resImg))
imagedestroy($resImg)
if (isset($res_thumb))
imagedestroy($res_thumb)
return $outFile
}
}