/**
* 将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. MySQL如何使用索引

    初始化测试数据 创建一个测试用的表 create table dept(id int primary key auto_increment , deptName varchar(32) not nul ...

  2. 能不能在FOR循环中执行SQL?

    JDBC最基础的For循环处理SQL的方式 以及执行时间 package javaee.net.cn.jdbc; import java.sql.*; public class TestTransac ...

  3. 【详记MySql问题大全集】二、安装并破解Navicat

    Navicat for MySql 11.1.13 企业版 下载地址: 链接:https://pan.baidu.com/s/1N3ZQXNyx-W8D4AsuZdsMug 密码:x0rd 第二个是N ...

  4. 神奇的CSS3混合模式

    神奇的css3混合模式 对于前端开发人员应该都很熟悉Photoshop的图层混合模式,就是几个图层按不同的模式进行混合,实现不同的图像效果.但是当我们前端同学在切这些效果图的时候,基本上就是一刀切的, ...

  5. iOS学习——(转)iOS中关于通知的使用

    在移动端开打过程中,经常会用到通知和推送,例如有短信来了需要通知提示,手机横屏了需要通知提示,插上耳机了需要通知提示等等,我们可以根据这些通知采取对应的动作.iOS系统自身定义了很对通知,但是在开发过 ...

  6. JSON库的使用研究(三)

    怎么选择JSON库? 从整体测试结果来看,总结如下: 用于序列化.反序列的功能,数量量小,吞吐量不大于10000每秒的,选择gson: 用于解析JSON的,还是用Fastjson吧,虽然听说坑很多. ...

  7. Xamarin.Android 开发中遇到旋转屏幕错误

    错误信息 : System.NotSupportedException: Unable to find the default constructor on type App5.MyFragment. ...

  8. springBoot(4)---热部署,配置文件使用

    热部署,配置文件使用 一.热加载 spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Sprin ...

  9. mybatis框架(2)---mapper代理方法

    mapper代理方法 在我们在写MVC设计的时候,都会写dao层和daoimp实现层,但假如我们使用mapper代理的方法,我们就可以不用先daoimp实现类 当然这得需要遵守一些相应的规则: (1) ...

  10. mysql 开发进阶篇系列 8 锁问题 (共享锁与排它锁演示)

    1 .innodb 共享锁(lock in share mode)演示 会话1 会话2 SET autocommit=0; SELECT cityname FROM  city WHERE city_ ...