js上传图片处理:压缩,旋转校正图片

随着科技发展的浪潮,手机上的摄像机的像素越来越高,成像的效果也越来越好。到现在一张手机拍摄的图片在 2M 左右是很正常的。在实际的应用场景中经常需要用户上传图片这样的人机交互方式。为了提高用户体验,上传图片之前要进行压缩。部分手机拍摄的图片会带有拍摄方向(如魅族,苹果),在上传之前就需要进行图片修正。案例中使用了 html5 的一些 API 对图片进行压缩; exif.js 的 EXIF.getDate(image, callback) API 获取图片的拍摄方向判断校正。
exif.js 相关资料:
https://github.com/exif-js/exif-js
http://code.ciaoca.com/javascript/exif-js/

html5 使用到的相关API
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
https://developer.mozilla.org/en-US/docs/Web/API/FileReader
https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/drawImage
https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Using_images

1、添加 change 监听事件。当用户选择好图片后,使用 FileReader 读取图片文件。
2、获取到图片后使用 exif.js 的 EXIF.getDate(image, callback) API 获取图片的拍摄方向,根据拍摄方向进行不同角度的旋转
3、根据图片大小进行判断是否需要压缩

1988

html DEMO:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <script src="jquery-3.1.0.min.js"></script>
    <script src="exif.js"></script>
    <script src="image.js"></script>
</head>
<body>
<form>
    <input id="image" type="file" accept="*">
</form>
<div id="show"></div>
</body>

<script>
    $(function () {
        var async = {};
        //处理图片后进行的操作,如上传
        async.do = function () {
            var imageData = $('#show>img')[0].src;//获取base64格式的图片
            var imageData = imageData.replace(/data:image\/jpeg;base64,/,'');//去掉"data:image/jpeg;base64,"
            //上传图片
            $.post('getImage.php',{image:imageData,lrj:'hhh'},function (data) {
                console.log(data)
            })
        };
        var source = $('#image');
        var show = $('#show')
        imageProcess(source, show, async)
    })
</script>
</html>

图片质量对比
对比
image.js:

/**
 * Created by ROOT on 2016/12/14.
 */

/**
 * @param source    图片源的表单
 * @param show      要展示图片的div
 * @param async     图片处理完成后要进行的操作,如ajax上传。等信息
 */
function imageProcess(source,show,async) {
    //监听图片源表单的改变事件
    source.change(function () {
        var files = this.files;
        if(files.length){
            var isImage = checkFile(this.files);
            if(!isImage){
                show.html("请确保文件为图像类型");
            }else{
                var reader = new FileReader();
                reader.onload = function(e){
                    var imageSize = e.total;//图片大小
                    var image = new Image();
                    image.src = e.target.result;
                    image.onload = function () {
                        // 旋转图片
                        var newImage = rotateImage(image)
                        // console.log(newImage)

                        //压缩图片
                        newImage = judgeCompress(newImage,imageSize);
                        newImage.setAttribute('width','100%');
                        show.html(newImage);
                        async.do();
                    }
                }
                reader.readAsDataURL(isImage);
            }
        }
    })
}

/**
 * 检查文件是否为图像类型
 * @param files         FileList
 * @returns file        File
 */
function checkFile(files){
    console.log(files)
    var file = files[0];
    //使用正则表达式匹配判断
    if(!/image\/\w+/.test(file.type)){
        return false;
    }
    return file;
}

/**
 * 判断图片是否需要压缩
 * @param image          HTMLImageElement
 * @param imageSize      int
 * @returns {*}          HTMLImageElement
 */
function judgeCompress(image,imageSize) {

    //判断图片是否大于300000 bit
    var threshold = 300000;//阈值,可根据实际情况调整
    console.log('imageSize:'+imageSize)
    if(imageSize>threshold){
        var imageData = compress(image);

        var newImage = new Image()
        newImage.src = imageData
        return newImage;
    }else {
        return image;
    }
}

/**
 *压缩图片
 * @param image         HTMLImageElement
 * @returns {string}    base64格式图像
 */
function compress(image) {
    console.log('compress');
    console.log(image)

    var canvas = document.createElement('canvas')
    var ctx = canvas.getContext('2d');

    var imageLength = image.src.length;
    var width = image.width;
    var height = image.height;

    canvas.width = width;
    canvas.height = height;

    ctx.drawImage(image, 0, 0, width, height);

    //压缩操作
    var quality = 0.1;//图片质量  范围:0<quality<=1 根据实际需求调正
    var imageData = canvas.toDataURL("image/jpeg", quality);

    console.log("压缩前:" + imageLength);
    console.log("压缩后:" + imageData.length);
    console.log("压缩率:" + ~~(100 * (imageLength - imageData.length) / imageLength) + "%");
    return imageData;
}


/**
 * 旋转图片
 * @param image         HTMLImageElement
 * @returns newImage    HTMLImageElement
 */
function rotateImage(image) {
    console.log('rotateImage');

    var width = image.width;
    var height = image.height;

    var canvas = document.createElement("canvas")
    var ctx = canvas.getContext('2d');

    var newImage = new Image();

    //旋转图片操作
    EXIF.getData(image,function () {
            var orientation = EXIF.getTag(this,'Orientation');
            // orientation = 6;//测试数据
            console.log('orientation:'+orientation);
            switch (orientation){
                //正常状态
                case 1:
                    console.log('旋转0°');
                    // canvas.height = height;
                    // canvas.width = width;
                    newImage = image;
                    break;
                //旋转90度
                case 6:
                    console.log('旋转90°');
                    canvas.height = width;
                    canvas.width = height;
                    ctx.rotate(Math.PI/2);
                    ctx.translate(0,-height);

                    ctx.drawImage(image,0,0)
                    imageDate = canvas.toDataURL('Image/jpeg',1)
                    newImage.src = imageDate;
                    break;
                //旋转180°
                case 3:
                    console.log('旋转180°');
                    canvas.height = height;
                    canvas.width = width;
                    ctx.rotate(Math.PI);
                    ctx.translate(-width,-height);

                    ctx.drawImage(image,0,0)
                    imageDate = canvas.toDataURL('Image/jpeg',1)
                    newImage.src = imageDate;
                    break;
                //旋转270°
                case 8:
                    console.log('旋转270°');
                    canvas.height = width;
                    canvas.width = height;
                    ctx.rotate(-Math.PI/2);
                    ctx.translate(-height,0);

                    ctx.drawImage(image,0,0)
                    imageDate = canvas.toDataURL('Image/jpeg',1)
                    newImage.src = imageDate;
                    break;
                //undefined时不旋转
                case undefined:
                    console.log('undefined  不旋转');
                    newImage = image;
                    break;
            }
        }
    );
    return newImage;
}

getImage.php:

<?php
/**
 * Created by PhpStorm.
 * User: 6500
 * Date: 2017/4/5
 * Time: 18:10
 */

$imagePath = './uploadPicture.jpg';//图片保存路径
$image = base64_decode($_POST['image']);
$newFile = fopen($imagePath,'w');
$fwriteRes = fwrite($newFile,$image);
fclose($newFile);
if ($fwriteRes){
    echo 'success';
}
  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值