common.js
export const common = {
// 这里的获取exif要将图片转ArrayBuffer对象,这里假设获取了图片的baes64
// 步骤一
// base64转ArrayBuffer对象
base64ToArrayBuffer: (base64) => {
base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '')
var binary = atob(base64) //atob() 方法用于解码使用 base-64 编码的字符串,windows对象里的方法
var len = binary.length
var buffer = new ArrayBuffer(len) // 创建一个binary.length字节的ArrayBuffer
var view = new Uint8Array(buffer)//创建一个buffer的引用,类型是Uint8,起始位置在0,结束位置为缓冲区尾部
for (var i = 0; i < len; i++) {
view[i] = binary.charCodeAt(i) //在引用指定位置里存入指定位置的字符的 Unicode 编码
}
return buffer //最终生成一个数组缓冲区,里面存储了该base64图片的二进制信息 ,为了后续通过底层接口拿到多种数值类型
},
// 步骤二,Unicode码转字符串
// ArrayBuffer对象 Unicode码转字符串
getStringFromCharCode: (dataView, start, length) => {
var str = ''
var i
for (i = start, length += start; i < length; i++) {
str += String.fromCharCode(dataView.getUint8(i))
}
return str //将第一步中的二进制ArrayBuffer对象生成的unicode的码转成字符串
},
// 步骤三,获取jpg图片的exif的角度(在ios体现最明显)下面很多都是为了获取图片数值的底层信息,陌生的大家可以一个个查,或者去看extjs官网
getOrientation: (arrayBuffer) => {
var dataView = new DataView(arrayBuffer) //可以从 二进制[`ArrayBuffer`]对象中读写多种数值类型的底层接口
var length = dataView.byteLength
var orientation
var exifIDCode
var tiffOffset
var firstIFDOffset
var littleEndian
var endianness
var app1Start
var ifdStart
var offset
var i
// Only handle JPEG image (start by 0xFFD8)
if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
offset = 2
while (offset < length) {
if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
app1Start = offset
break
}
offset++
}
}
if (app1Start) {
exifIDCode = app1Start + 4
tiffOffset = app1Start + 10
if (common.getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
endianness = dataView.getUint16(tiffOffset)
littleEndian = endianness === 0x4949
if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian)
if (firstIFDOffset >= 0x00000008) {
ifdStart = tiffOffset + firstIFDOffset
}
}
}
}
}
if (ifdStart) {
length = dataView.getUint16(ifdStart, littleEndian)
var standalone = window.navigator.standalone,
userAgent = window.navigator.userAgent.toLowerCase(),
safari = /safari/.test(userAgent),
ios = /iphone|ipod|ipad/.test(userAgent)
for (i = 0; i < length; i++) {
offset = ifdStart + i * 12 + 2
if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
// 8 is the offset of the current tag's value
offset += 8
// Get the original orientation value
orientation = dataView.getUint16(offset, littleEndian)
// Override the orientation with its default value for Safari (#120)
// if (IS_SAFARI_OR_UIWEBVIEW) {
// dataView.setUint16(offset, 1, littleEndian);
// }
if (ios) {
if (!standalone && safari) {
dataView.setUint16(offset, 1, littleEndian)
} else if (standalone && !safari) {
//standalone
} else if (!standalone && !safari) {
dataView.setUint16(offset, 1, littleEndian)
};
}
break
}
}
}
return orientation
}
}
图片转为base64
urlTobase64 (url) {
uni.request({
url: url,
method: 'GET',
responseType: 'arraybuffer',
success: (res) => {
let base64 = uni.arrayBufferToBase64(res.data) //把arraybuffer转成base64
base64 = 'data:image/jpeg;base64,' + base64 //不加上这串字符,在页面无法显示
const or = common.getOrientation(common.base64ToArrayBuffer(base64))
ImageCompress(base64, or)
}
})
}
压缩图片
function ImageCompress (file, Orientation) {
var file,
image = new Image()
if (file) {
image.src = file
image.onload = function () {
var imgWidth = this.width,
imgHeight = this.height,
maxWidth = 1280
// 控制上传图片的宽高
if (imgWidth > imgHeight && imgHeight > maxWidth) {
imgWidth = maxWidth
imgHeight = Math.ceil(maxWidth * this.height / this.width)
} else if (imgWidth < imgHeight && imgWidth > maxWidth) {
imgWidth = Math.ceil(maxWidth * this.width / this.height)
imgHeight = maxWidth
}
var canvas = document.createElement("canvas"),
ctx = canvas.getContext('2d')
canvas.width = imgWidth
canvas.height = imgHeight
if (Orientation && Orientation != 1) {
switch (Orientation) {
case 6: // 旋转90度
canvas.width = imgHeight
canvas.height = imgWidth
ctx.rotate(Math.PI / 2)
// (0,-imgHeight) 从旋转原理图那里获得的起始点
ctx.drawImage(this, 0, -imgHeight, imgWidth, imgHeight)
break
case 3: // 旋转180度
ctx.rotate(Math.PI)
ctx.drawImage(this, -imgWidth, -imgHeight, imgWidth, imgHeight)
break
case 8: // 旋转-90度
canvas.width = imgHeight
canvas.height = imgWidth
ctx.rotate(3 * Math.PI / 2)
ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight)
break
}
} else {
ctx.drawImage(this, 0, 0, imgWidth, imgHeight)
}
var ndata = canvas.toDataURL("image/jpeg", 0.98) // 压缩质量为0.98 压缩图片路径
}
}
}