/**
* 将base64转换为文件对象
* (即用文件上传输入框上传文件得到的对象)
* @param {String} base64 base64字符串
*/
function convertBase64UrlToBlob(base64){
var base64Arr = base64.split(',');
if(base64Arr.length > ){
//如果是图片base64,去掉头信息
base64 = base64Arr[];
}
// 将base64解码
var bytes = atob(base64);
var bytesCode = new ArrayBuffer(bytes.length);
// 将base64转换为ascii码
for (var i = ; i < bytes.length; i++) {
bytesCode[i] = bytes.charCodeAt(i);
}
// 转换为类型化数组
var byteArray = new Uint8Array(bytesCode);
// 生成Blob对象(文件对象)
return new Blob( [byteArray] , {type : 'image/png'});
}
/**
* 压缩图片
* (压缩后返回的是base64,可以参照本目录下的convertBase64ToBlob.js,将base64还原为file input读取得到的文件对象)
* @param {Dom Object} $fileInput 文件上传输入框
* @param {Function} callback 压缩完成后的回调函数
* @return {Object} options 指定压缩到指定体积以下或按比率压缩,不指定不会压缩
*/
function compressImg($fileInput, callback, options) {
options = options || {};
// 绑定change事件
$fileInput.onchange = function ($event) {
var $target = $event.target;
if ($target.files && $target.files[]) {
// 用FileReader读取文件
var reader = new FileReader();
// 将图片读取为base64
reader.readAsDataURL($fileInput.files[]);
reader.onload = function(evt){
var base64 = evt.target.result;
// 创建图片对象
var img = new Image();
// 用图片对象加载读入的base64
img.src = base64;
img.onload = function () {
var that = this,
canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.setAttribute('width', that.width);
canvas.setAttribute('height', that.height);
// 将图片画入canvas
ctx.drawImage(that, , , that.width, that.height);
// 压缩到指定体积以下(M)
if(options.size){
var scale = 0.9;
while (base64.length / / > options.size) {
// 用canvas的toDataURL方法实现压缩
base64 = canvas.toDataURL('image/jpeg', scale);
// 降低压缩比率,直到压缩结果小于指定大小
scale = scale - 0.1;
}
} else if(options.scale){
// 按比率压缩
base64 = canvas.toDataURL('image/jpeg', options.scale);
}
callback(base64);
}
}
}
}
}
/**
* 上传之前预览图片
* @param {Dom Object} $fileInput 文件上传输入框
* @param {Dom Object} $previewImg 预览图片的image元素
*/
function previewImg($fileInput, $previewImg) {
$fileInput.onchange = function ($event) {
var $target = $event.target;
if ($target.files && $target.files[]) {
var reader = new FileReader();
reader.readAsDataURL($target.files[]);
reader.onload = function(evt){
var base64 = evt.target.result;
$previewImg.setAttribute('src', base64);
}
}
}
}
/**
* 将图片旋转到正确的角度
* (解决移动端上传的图片角度不正确的问题)
* (旋转后返回的是base64,可以参照本目录下的convertBase64ToBlob.js,将base64还原为file input读取得到的文件对象)
* @param {Dom Object} $fileInput 文件上传输入框
* @param {Function} callback 旋转完成后的回调函数
*/
function resetImgOrientation($fileInput, callback) {
// 绑定change事件
$fileInput.onchange = function ($event) {
var $target = $event.target;
if ($target.files && $target.files[]) {
// 获取图片旋转角度
getOrientation($target.files[], function (orientation) {
var reader = new FileReader();
reader.readAsDataURL($target.files[]);
reader.onload = function(evt){
var base64 = evt.target.result;
// 将图片旋转到正确的角度
resetOrientation(base64, orientation, function (resultBase64) {
callback(resultBase64);
});
}
});
}
}
} // 获取图片旋转的角度
function getOrientation(file, callback) {
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function(e) {
var view = new DataView(e.target.result);
if (view.getUint16(, false) != 0xFFD8) return callback(-);
var length = view.byteLength, offset = ;
while (offset < length) {
var marker = view.getUint16(offset, false);
offset += ;
if (marker == 0xFFE1) {
if (view.getUint32(offset += , false) != 0x45786966) return callback(-);
var little = view.getUint16(offset += , false) == 0x4949;
offset += view.getUint32(offset + , little);
var tags = view.getUint16(offset, little);
offset += ;
for (var i = ; i < tags; i++)
if (view.getUint16(offset + (i * ), little) == 0x0112)
return callback(view.getUint16(offset + (i * ) + , little));
}
else if ((marker & 0xFF00) != 0xFF00) break;
else offset += view.getUint16(offset, false);
}
return callback(-);
};
}
// 将图片旋转到正确的角度
function resetOrientation(srcBase64, srcOrientation, callback) {
var img = new Image();
img.onload = function() {
var width = img.width,
height = img.height,
canvas = document.createElement('canvas'),
ctx = canvas.getContext("2d");
// set proper canvas dimensions before transform & export
if ([,,,].indexOf(srcOrientation) > -) {
canvas.width = height;
canvas.height = width;
} else {
canvas.width = width;
canvas.height = height;
}
// transform context before drawing image
switch (srcOrientation) {
case : ctx.transform(-, , , , width, ); break;
case : ctx.transform(-, , , -, width, height ); break;
case : ctx.transform(, , , -, , height ); break;
case : ctx.transform(, , , , , ); break;
case : ctx.transform(, , -, , height , ); break;
case : ctx.transform(, -, -, , height , width); break;
case : ctx.transform(, -, , , , width); break;
default: ctx.transform(, , , , , );
}
// draw image
ctx.drawImage(img, , );
// export base64
callback(canvas.toDataURL('image/jpeg'));
};
img.src = srcBase64;
};

file上传图片,base64转换、压缩图片、预览图片、将图片旋转到正确的角度的更多相关文章

  1. WPF图片预览之移动、旋转、缩放

    原文:WPF图片预览之移动.旋转.缩放 RT,这个功能比较常见,但凡涉及到图片预览的都跑不了,在说自己的实现方式前,介绍一个好用的控件:Extended.Toolkit中的Zoombox,感兴趣的同学 ...

  2. Java带图片预览功能的图片上传兼容火狐ie

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. js实现移动端图片预览:手势缩放, 手势拖动,双击放大...

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  4. vue常用插件之图片预览

    v-viewer(1.4.2) 非常实用的图片预览插件,支持旋转.缩放.翻转等操作 一.npm安装 npm i v-viewer -S 二.全局引入(main.js中) import 'viewerj ...

  5. Wx-小程序-图片预览、保存

    点击图片预览 长按图片保存 点击按钮保存到手机相册 view: <!--wxml--> <text>点击图片预览.长按保存图片.点击按钮保存到系统相册</text> ...

  6. jquery解决file上传图片+图片预览

    js解决file上传图片+图片预览 demo案例中代码为js原生控制,可以根据项目的需求修改为jquery操作 <!DOCTYPE html><html lang="en& ...

  7. 一段上传图片预览JS脚本,Input file图片预览的实现

    在深圳做项目的时候,需要一个用户上传头像预览的功能!是在网上找了好多,都不太满意.要么是flash的,要么是Ajax上传后返回图片路径的,要么压根就是不能用的.幸运的是在这个项目以前有人写过一个图片预 ...

  8. html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器

    以前写过上传组件,见 打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器,对付一般的上传没有问题,不过如果是上传图片,且需要预览的话,就力有不逮了,趁着闲暇时间,给上 ...

  9. H5图片预览、压缩、上传

    目标实现: 1.选择图片, 前端预览效果 2.图片大于1.2M的时候, 对图片进行压缩 3.以表单的形式上传图片 4.图片删除 预览效果图: 代码说明: 1.input:file选择图片 <!- ...

随机推荐

  1. SpringMVC 使用 MultipartFile 实现文件上传

    该代码实现了文件上传和文本字段同时传递到后台进行处理的功能. 直接贴代码,中间涉及到的实体类就不贴了,和功能没啥关系的. Controller /** * 添加活动 * * @param req * ...

  2. 第74节:Java中的Cookie和Session

    第74节:第74节:Java中的Cookie和Session ServletContext: 什么是ServletContext,有什么用哦,怎么用呢? 启动服务器后,会给每个应用程序创建一个Serv ...

  3. Python - 调试Python代码的方法

    调试(debug) 将可疑环节的变量逐步打印出来,从而检查哪里是否有错. 让程序一部分一部分地运行起来.从核心功能开始,写一点,运行一点,再修改一点. 利用工具,例如一些IDE中的调试功能,提高调试效 ...

  4. 过了所有技术面,却倒在 HR 一个问题上。。

    面试问离职原因,这是我们广大程序员朋友面试时逃不开的问题,如果答得不好,可能就影响了你整个的面试结果. 最近在栈长的Java技术栈vip群里,我也看到大家在讨论这个问题,其中有个朋友的回复栈长很有感触 ...

  5. th:标签

    https://blog.csdn.net/xxb5502296/article/details/78319898(挺全的) https://blog.csdn.net/qq_43279637/art ...

  6. mysql 开发进阶篇系列 10 锁问题 (相同索引键值或同一行或间隙锁的冲突)

    1.使用相同索引键值的冲突 由于mysql 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但如果是使用相同的索引键,是会出现锁冲突的.设计时要注意 例如:city表city_ ...

  7. springboot Aop 统一处理Web请求日志

    1.增加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  8. [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. 文章Points: 1.不认识到犯错,然后得到 ...

  9. Deploying Keras model on Tensorflow Serving--

    keras训练了个二分类的模型.需求是把keras模型跑到 tensorflow serving上 (TensorFlow Serving 系统用于在生产环境中运行模型) keras模型转 tenso ...

  10. 搞懂Python的类和对象名称空间

    代码块的分类 python中分几种代码块类型,它们都有自己的作用域,或者说名称空间: 文件或模块整体是一个代码块,名称空间为全局范围 函数代码块,名称空间为函数自身范围,是本地作用域,在全局范围的内层 ...