JS implements image base64 to blob object, compress image, preview image, rotate image to correct angle

base64 to blob object

/** Convert base64 to file object
 *  @param {String} base64 base64 Character string
 * */
var convertBase64ToBlob = function(base64){
    var base64Arr = base64.split(',');
    var imgtype = '';
    var base64String = '';
    if(base64Arr.length > 1){
        //If it's a picture base64,Remove header information
        base64String = base64Arr[1];
        imgtype = base64Arr[0].substring(base64Arr[0].indexOf(':')+1,base64Arr[0].indexOf(';'));
    }
    // take base64 Decode
    var bytes = atob(base64String);
    //var bytes = base64;
    var bytesCode = new ArrayBuffer(bytes.length);
     // Convert to typed array
    var byteArray = new Uint8Array(bytesCode);
    
    // take base64 Convert to ascii code
    for (var i = 0; i < bytes.length; i++) {
        byteArray[i] = bytes.charCodeAt(i);
    }
   
    // generate Blob Object (file object)
    return new Blob( [bytesCode] , {type : imgtype});
};

Compress pictures

/** Compress pictures
 * @param {Object} file Upload object files[0]
 * @param {Object} options Compression settings object
 * @param {Function} callback Callback function
 * @result {Object} Return blob file object
 * */
var compressImg = function(file,options,callback){
    var self = this;
    var imgname = file.name;
    var imgtype = (imgname.substring(imgname.lastIndexOf('.') + 1)).toLowerCase();
    if(imgtype == 'jpg' || imgtype == 'jpeg'){
        imgtype = 'image/jpeg';
    }else{
        imgtype = 'image/png';
    }
    // use FileReader read file
    var reader = new FileReader();
    // Read picture as base64
    reader.readAsDataURL(file);
    reader.onload = function(evt){
        var base64 = evt.target.result;
        // Create a picture object
        var img = new Image();
        // Load read in with picture object 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);
            // Draw picture into canvas
            ctx.drawImage(that, 0, 0, that.width, that.height);
            
            // Compress below specified volume( M)
            if(options.size){
                var scale = 0.9;
                (function f(scale){
                    if(base64.length / 1024 / 1024 > options.size && scale > 0){
                        base64 = canvas.toDataURL(imgtype, scale);
                        scale = scale - 0.1;
                        f(scale);
                    }else{
                        callback(base64);
                        
                    }
                })(scale); 
            } else if(options.scale){
                // Compress by ratio
                base64 = canvas.toDataURL(imgtype, options.scale);
                callback(base64);
            }
            
        }
    }
};

Picture preview

/**
 * Picture preview
 * @param {Object} $fileInput File upload file
 * @param {Object} $previewImg image element of preview picture
 */
function previewImg($fileInput, $previewImg) {
    $fileInput.onchange = function ($event) {
        var $target = $event.target;
        if ($target.files && $target.files[0]) {
            var reader = new FileReader();
            reader.onload = function(evt){
                $previewImg.src = evt.target.result;
            }
            reader.readAsDataURL($target.files[0]);
        }
    }
}

For detailed picture preview, please refer to:< After the Image load event (onload) and the load state (complete) are clarified, the local preview of the Image is realized and adapted to the parent element (complete)>

Rotate the picture to the right angle (verify it is feasible)

/**
 * Rotate the picture to the right angle
 * (Solve the problem that the angle of pictures uploaded by the mobile terminal is not correct)
 * (After rotation, base64 is returned. You can refer to convertBase64ToBlob.js in this directory to restore base64 to the file object read from file input.)
 * @param {Dom Object} $fileInput File upload input box
 * @param {Function} callback Callback function after rotation
 */
function resetImgOrientation($fileInput, callback) {
    // binding change Event
    $fileInput.onchange = function ($event) {
        var $target = $event.target;
        if ($target.files && $target.files[0]) {
            // Get picture rotation angle
            getOrientation($target.files[0], function (orientation) {
                var reader = new FileReader();
                reader.readAsDataURL($target.files[0]);
                reader.onload = function(evt){
                    var base64 = evt.target.result;
                    // Rotate the picture to the right angle
                    resetOrientation(base64, orientation, function (resultBase64) {
                        callback(resultBase64);
                    });
                }
            });
        }
    }
}

// Get the angle of picture rotation
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(0, false) != 0xFFD8) return callback(-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 callback(-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 callback(view.getUint16(offset + (i * 12) + 8, little));
            }
            else if ((marker & 0xFF00) != 0xFF00) break;
            else offset += view.getUint16(offset, false);
        }
        return callback(-1);
    };
}
// Rotate the picture to the right angle
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 ([5,6,7,8].indexOf(srcOrientation) > -1) {
            canvas.width = height;
            canvas.height = width;
        } else {
            canvas.width = width;
            canvas.height = height;
        }
        // transform context before drawing image
        switch (srcOrientation) {
            case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
            case 3: ctx.transform(-1, 0, 0, -1, width, height ); break;
            case 4: ctx.transform(1, 0, 0, -1, 0, height ); break;
            case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
            case 6: ctx.transform(0, 1, -1, 0, height , 0); break;
            case 7: ctx.transform(0, -1, -1, 0, height , width); break;
            case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
            default: ctx.transform(1, 0, 0, 1, 0, 0);
        }
        // draw image
        ctx.drawImage(img, 0, 0);
        // export base64
        callback(canvas.toDataURL('image/jpeg'));
    };
    img.src = srcBase64;
};

Reference address:

file upload picture, base64 convert, compress picture, preview picture, rotate picture to correct angle
H5 image compression and upload

Accessing JPEG EXIF rotation data in JavaScript on the client side

Tags: Javascript ascii Mobile

Posted on Mon, 30 Mar 2020 10:15:17 -0700 by cityguru