图片各类处理
function detectVerticalSquash ( img ) {
var data;
var ih = img. naturalHeight;
var canvas = document. createElement ( 'canvas' ) ;
canvas. width = 1 ;
canvas. height = ih;
var ctx = canvas. getContext ( '2d' ) ;
ctx. drawImage ( img, 0 , 0 ) ;
try {
data = ctx. getImageData ( 0 , 0 , 1 , ih) . data;
} catch ( err) {
console. log ( 'Cannot check verticalSquash: CORS?' ) ;
return 1 ;
}
var sy = 0 ;
var ey = ih;
var py = ih;
while ( py > sy) {
var alpha = data[ ( py - 1 ) * 4 + 3 ] ;
if ( alpha === 0 ) {
ey = py;
} else {
sy = py;
}
py = ( ey + sy) >> 1 ;
}
var ratio = py / ih;
return ratio === 0 ? 1 : ratio;
}
function dataURItoBuffer ( dataURI ) {
var byteString = atob ( dataURI. split ( ',' ) [ 1 ] ) ;
var buffer = new ArrayBuffer ( byteString. length) ;
var view = new Uint8Array ( buffer) ;
for ( var i = 0 ; i < byteString. length; i++ ) {
view[ i] = byteString. charCodeAt ( i) ;
}
return buffer;
}
function dataURItoBlob ( dataURI ) {
var mimeString = dataURI. split ( ',' ) [ 0 ] . split ( ':' ) [ 1 ] . split ( ';' ) [ 0 ] ;
var buffer = dataURItoBuffer ( dataURI) ;
return new Blob ( [ buffer] , { type: mimeString } ) ;
}
function getOrientation ( buffer ) {
var view = new DataView ( buffer) ;
if ( view. getUint16 ( 0 , false ) != 0xffd8 ) return - 2 ;
var length = view. byteLength,
offset = 2 ;
while ( offset < length) {
var marker = view. getUint16 ( offset, false ) ;
offset += 2 ;
if ( marker == 0xffe1 ) {
if ( view. getUint32 ( ( offset += 2 ) , false ) != 0x45786966 ) return - 1 ;
var little = view. getUint16 ( ( offset += 6 ) , false ) == 0x4949 ;
offset += view. getUint32 ( offset + 4 , little) ;
var tags = view. getUint16 ( offset, little) ;
offset += 2 ;
for ( var i = 0 ; i < tags; i++ )
if ( view. getUint16 ( offset + i * 12 , little) == 0x0112 )
return view. getUint16 ( offset + i * 12 + 8 , little) ;
} else if ( ( marker & 0xff00 ) != 0xff00 ) break ;
else offset += view. getUint16 ( offset, false ) ;
}
return - 1 ;
}
function orientationHelper ( canvas, ctx, orientation ) {
const w = canvas. width,
h = canvas. height;
if ( orientation > 4 ) {
canvas. width = h;
canvas. height = w;
}
switch ( orientation) {
case 2 :
ctx. translate ( w, 0 ) ;
ctx. scale ( - 1 , 1 ) ;
break ;
case 3 :
ctx. translate ( w, h) ;
ctx. rotate ( Math. PI ) ;
break ;
case 4 :
ctx. translate ( 0 , h) ;
ctx. scale ( 1 , - 1 ) ;
break ;
case 5 :
ctx. rotate ( 0.5 * Math. PI ) ;
ctx. scale ( 1 , - 1 ) ;
break ;
case 6 :
ctx. rotate ( 0.5 * Math. PI ) ;
ctx. translate ( 0 , - h) ;
break ;
case 7 :
ctx. rotate ( 0.5 * Math. PI ) ;
ctx. translate ( w, - h) ;
ctx. scale ( - 1 , 1 ) ;
break ;
case 8 :
ctx. rotate ( - 0.5 * Math. PI ) ;
ctx. translate ( - w, 0 ) ;
break ;
}
}
export function compress ( file, options, callback ) {
const reader = new FileReader ( ) ;
reader. onload = function ( evt ) {
if ( options. compress === false ) {
file. base64 = evt. target. result;
callback ( file) ;
return ;
}
const img = new Image ( ) ;
img. onload = function ( ) {
const ratio = detectVerticalSquash ( img) ;
const orientation = getOrientation ( dataURItoBuffer ( img. src) ) ;
const canvas = document. createElement ( 'canvas' ) ;
const ctx = canvas. getContext ( '2d' ) ;
const maxW = options. compress. width;
const maxH = options. compress. height;
let w = img. width;
let h = img. height;
let dataURL;
if ( w < h && h > maxH) {
w = parseInt ( ( maxH * img. width) / img. height) ;
h = maxH;
} else if ( w >= h && w > maxW) {
h = parseInt ( ( maxW * img. height) / img. width) ;
w = maxW;
}
canvas. width = w;
canvas. height = h;
if ( orientation > 0 ) {
orientationHelper ( canvas, ctx, orientation) ;
}
ctx. drawImage ( img, 0 , 0 , w, h / ratio) ;
if ( / image\/jpeg / . test ( file. type) || / image\/jpg / . test ( file. type) ) {
dataURL = canvas. toDataURL ( 'image/jpeg' , options. compress. quality) ;
} else {
dataURL = canvas. toDataURL ( file. type) ;
}
if ( options. type == 'file' ) {
if ( / ;base64,null / . test ( dataURL) || / ;base64,$ / . test ( dataURL) ) {
console. warn (
'Compress fail, dataURL is ' +
dataURL +
'. Next will use origin file to upload.'
) ;
callback ( file) ;
} else {
let blob = dataURItoBlob ( dataURL) ;
blob. id = file. id;
blob. name = file. name;
blob. lastModified = file. lastModified;
blob. lastModifiedDate = file. lastModifiedDate;
callback ( blob) ;
}
} else {
if ( / ;base64,null / . test ( dataURL) || / ;base64,$ / . test ( dataURL) ) {
options. onError (
file,
new Error ( 'Compress fail, dataURL is ' + dataURL + '.' )
) ;
callback ( ) ;
} else {
file. base64 = dataURL;
callback ( file) ;
}
}
} ;
img. src = evt. target. result;
} ;
reader. readAsDataURL ( file) ;
}
export function completePictureBase64 ( suffix, file ) {
if ( suffix === 'png' ) {
return 'data:image/png;base64,' + file
} else {
return 'data:image/jpeg;base64,' + file
}
}