H5调用手机摄像头,实现图片旋转(校正)功能,图片的工具类等
为什么要是用h5调用呢?这个方案在手机端是通用方案,不管是将页面嵌入到哪一个平台,都能实现调用。
这里拍摄的图片是使用base64的方式回显到页面上,因此没有和后台交互。
这里再浏览器上做个演示,手机不好录,效果如下
首先我们要借助工具 exif.js
在百度上搜索即可下载这个js文件,然后导入即可。
此外,什么是EXIF?
通俗的讲,Exif 信息就是由数码相机当然包含我们手机的相机,它在拍摄过程中采集一系列的信息,然后把信息放置在我们熟知的 JPEG/TIFF 文件的头部,也就是说 Exif信息是镶嵌在 JPEG/TIFF 图像文件格式内的一组拍摄参数,它就好像是傻瓜相机的日期打印功能一样,只不过 Exif信息所记录的资讯更为详尽和完备。Exif 所记录的元数据信息非常丰富,这就可以解释,我们再ps过图片后为什么通过某些技术手段是可以辨认出这张图片是经过修改后的图片,包含图片的后缀等等一些信息,其实我们通过文本的的方式打开这个图片,某些字眼我们是可以辨认出的,知道它所表达的含义。其中,通过exif我们可以获取包含了以下几类信息的内容:
1.拍摄日期
2.摄器材(机身、镜头、闪光灯等
3.拍摄参数(快门速度、光圈F值、ISO速度、焦距、测光模式等
4.图像处理参数(锐化、对比度、饱和度、白平衡等)
5.图像描述及版权信息
6.GPS定位数据
7.缩略图
它的数值分别代表什么?
我们通过这些参数是可以获取到图片的旋转角度,然后将安卓拍摄后的照片进行旋转。注意
: 如果使用电脑的浏览器进行上传图片,这个Orientation的值将会是undefine,为什么呢,因为浏览器上传的图片并不一定是数码设备拍摄的(电脑截图就不是),因此,这种情况就是另说了,而且这种情况图片是正立的并不需要旋转,因此不处理即可。
下面就是主要代码,适配的安卓,粘贴上去就可使用,其中,里面用到了图片高度、宽度、和图片质量压缩。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">
</script>
</head>
<body style="background:#f2f2f2">
<div ">
<form action="detail/add" method="post" >
<div class="banner1">
<div class=" pad30 font34 bcfff" style="border-bottom:1px solid #e6e6e6;position: relative;">
<div style="width:100%;height:40%;display:block;position: relative;">
<img class="img_up" id="img_up1" src="http://cdn.onlinewebfonts.com/svg/img_180334.png" style="width:100%;height:235px;object-fit:contain;display:block;position: relative;"
alt="">
<input type="file" name="file" id="imagefile" class="file" value="" onchange="imgChange(this)" accept="image/jpg,image/jpeg,image/png,image/bmp"
multiple="" style="position: absolute;width: 100%;right:0px;bottom:0px;opacity:0;z-index:8888;height: 100%;">
</div>
<input type="hidden" name="img" id="path1">
</div>
</form>
</div>
</body>
<script type="text/javascript" src="js/exif.js"></script>
<script>
function imgChange(node) {
var Orientation = null;
var imgURL = "";
var path = node.value;
//分类获取图片路径
var file = null;
try {
//获取文件内容
if (node.files && node.files[0]) {
file = node.files[0];
} else if (node.files && node.files.item(0)) {
file = node.files.item(0);
}
EXIF.getData(file, function() {
EXIF.getAllTags(this);
Orientation = EXIF.getTag(this, 'Orientation');
var oReader = new FileReader();
oReader.onload = function(e) {
var image = new Image();
image.src = e.target.result;
image.onload = function() {
var expectWidth = this.naturalWidth;
var expectHeight = this.naturalHeight;
//压缩图片可以按照这个比例进行配置 MAX_Width =200 MAX_HEIGHT = 300;
var MAX_Width = 400;
var MAX_HEIGHT = 600;
if (this.naturalWidth > this.naturalHeight && this.naturalWidth > MAX_Width) {
expectWidth = MAX_Width;
expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
} else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > MAX_HEIGHT) {
expectHeight = MAX_HEIGHT;
expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
}
canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
canvas.width = expectWidth;
canvas.height = expectHeight;
ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
var base64 = null;
if (Orientation != "" && Orientation != 1) {
switch (Orientation) {
case 6: //需要顺时针(向左)90度旋转
rotateImg(this, 'left', canvas);
break;
case 8: //需要逆时针(向右)90度旋转
rotateImg(this, 'right', canvas);
break;
case 3: //需要180度旋转
rotateImg(this, 'right', canvas); //转两次
rotateImg(this, 'right', canvas);
break;
}
}
//0.6表示图片的质量,0-1,1表示质量最好
base64 = canvas.toDataURL("image/jpeg", 0.6);
//这里可以使用base64方式,将图片传到后台.也可以在使用file进行上传
$("input[name='img']").val(base64.replace("data:image/jpeg;base64,", ""));
$(".img_up").attr("src", base64);
};
};
oReader.readAsDataURL(file);
});
} catch (e) {
if (node.files && node.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
imgURL = e.target.result;
};
reader.readAsDataURL(node.files[0]);
}
}
}
//对图片旋转处理
function rotateImg(img, direction, canvas) {
//alert(img);
//最小与最大旋转方向,图片旋转4次后回到原方向
var min_step = 0;
var max_step = 3;
//var img = document.getElementById(pid);
if (img == null)
return;
//img的高度和宽度不能在img元素隐藏后获取,否则会出错
var height = img.height;
var width = img.width;
//var step = img.getAttribute('step');
var step = 2;
if (step == null) {
step = min_step;
}
if (direction == 'right') {
step++;
//旋转到原位置,即超过最大值
step > max_step && (step = min_step);
} else {
step--;
step < min_step && (step = max_step);
}
//旋转角度以弧度值为参数
var degree = step * 90 * Math.PI / 180;
var ctx = canvas.getContext('2d');
switch (step) {
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0);
break;
}
}
</script>
</html>
这里介绍的仅仅是安卓,如果你有ios的需要,参考以下文章即可,相信你一定能行!
https://www.jb51.net/article/96539.htm
附上处理base64的工具类,使用以下工具可以直接将图片保存到本地路径下。
import java.io.*;
import org.springframework.web.bind.annotation.RequestBody;
import sun.misc.BASE64Decoder;
/**
* 文件读取工具类
*/
public class FileUtil {
/**
* 读取文件内容,作为字符串返回
*/
public static String readFileAsString(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
throw new FileNotFoundException(filePath);
}
if (file.length() > 1024 * 1024 * 1024) {
throw new IOException("File is too large");
}
StringBuilder sb = new StringBuilder((int) (file.length()));
// 创建字节输入流
FileInputStream fis = new FileInputStream(filePath);
// 创建一个长度为10240的Buffer
byte[] bbuf = new byte[10240];
// 用于保存实际读取的字节数
int hasRead = 0;
while ( (hasRead = fis.read(bbuf)) > 0 ) {
sb.append(new String(bbuf, 0, hasRead));
}
fis.close();
return sb.toString();
}
/**
* 根据文件路径读取byte[] 数组
*/
public static byte[] readFileByBytes(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
throw new FileNotFoundException(filePath);
} else {
ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(file));
short bufSize = 1024;
byte[] buffer = new byte[bufSize];
int len1;
while (-1 != (len1 = in.read(buffer, 0, bufSize))) {
bos.write(buffer, 0, len1);
}
byte[] var7 = bos.toByteArray();
return var7;
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException var14) {
var14.printStackTrace();
}
bos.close();
}
}
}
/**
* Base64转换文件 图片位置调整
* @param encode Base64
* @param fileName 文件名
* @param filePath 文件路径 例如:C:/filepath
* @return 文件路径
* @throws Exception
* @throws FileNotFoundException
*/
public static String outFile( String encode,String fileName,String filePath) throws Exception{
FileOutputStream out = null;
String outFilePath = null;
File file = new File(filePath);
if(!file.isDirectory()){
file.mkdirs();
}
//文件存储路径+文件名
File f = new File(file,fileName);
out = new FileOutputStream(f);
byte[] buffer = new BASE64Decoder().decodeBuffer(encode);
out.write(buffer);
outFilePath = f.getPath();
out.close();
return outFilePath;
}
/**
*
* @param path 文件全路径
* @param filePath 复制到那个文件下
*/
public static void copyFile(String path,String filePath){
if(path.equals(filePath)){
return;
}
File file =new File(path);
File copyFile=null;
copyFile = new File(filePath);
if(!file.exists()){
return;
}
if(!copyFile.exists()){
copyFile.getParentFile().mkdirs();
}
FileInputStream fis =null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file);
fos = new FileOutputStream(copyFile);
byte[] b = new byte[1024];
int len = -1;
while((len=fis.read(b))!=-1){
fos.write(b, 0, len);
}
}catch (IOException e) {
e.printStackTrace();
}finally{
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 剪切文件
* @param path 文件全路径
* @param filePath 复制到那个文件下
*/
public static void cutFile(String path,String filePath){
try{
copyFile(path,filePath);
File file = new File(path);
if(file.exists()){
file.delete();
}
}catch(Exception e){
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
cutFile(path,filePath);
}
}
/**
* @Description: 根据图片地址转换为base64编码字符串
* @Author:
* @CreateTime:
* @return
*/
public static String getImgBase64(String imgFile,int ii) {
InputStream inputStream = null;
byte[] data = null;
try {
String names[] = imgFile.split("/");
String filepath = null;
//图片的本地路径
filepath = "D:\\img\\"+names[names.length-1];
inputStream = new FileInputStream(filepath);
data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
}