php canvas 前端JS壓縮,獲取圖片二進制流數據並上傳

<?php
if(isset($_GET['upload']) && $_GET['upload'] == 'img'){
    //二進制數據流
    $data = file_get_contents ( 'php://input' );    // 不須要php.ini設置,內存壓力小
    if(empty($data)){
        $data = gzuncompress ( $GLOBALS ['HTTP_RAW_POST_DATA'] );    // 須要php.ini設置
    }
    if(imagecreatefromstring($data) == false){
        exit('圖片已損壞');
    }
    $filename=time().'.png';
    $ret = file_put_contents($filename, $data, true);
    exit('http://'.$_SERVER['HTTP_HOST'].'/'.$filename);
}
?>
<!DOCTYPE html>
<html>
<head>
</head>

<body>

<div id="main">
    <h1>使用canvas在前端壓縮圖片實例頁面</h1>
    <div id="body">
        <div id="effect" class="part">
            <h3>效果(400x400限制):</h3>
            <div class="show">
                <div class="demo">
                    <p><input id="file" type="file" accept="image/gif, image/png, image/jpg, image/jpeg"></p>
                    <p id="log"></p>
                </div>
            </div>
        </div>

    </div>
</div>

<script>
    // 寫log方法,演示輔助,與主邏輯無關
    var log = function (info) {
        document.getElementById('log').innerHTML += (info + '<br>');
    };

    var eleFile = document.querySelector('#file');

    if (window.FormData) {
        // 壓縮圖片須要的一些元素和對象
        var reader = new FileReader(), img = new Image();

        // 選擇的文件對象
        var file = null;

        // 縮放圖片須要的canvas
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');

        // base64地址圖片加載完畢後
        img.onload = function () {
            // 圖片原始尺寸
            var originWidth = this.width;
            var originHeight = this.height;

            log('圖片原尺寸是:' + [originWidth, originHeight].join('x'));

            // 計算出目標壓縮尺寸
            var maxWidth = 400, maxHeight = 400;

            // 目標尺寸
            var targetWidth = originWidth, targetHeight = originHeight;

            if (originWidth > maxWidth || originHeight > maxHeight) {
                // 圖片尺寸超過400x400的限制
                if (originWidth / originHeight > maxWidth / maxHeight) {
                    // 更寬,按照寬度限定尺寸
                    targetWidth = maxWidth;
                    targetHeight = Math.round(maxWidth * (originHeight / originWidth));
                } else {
                    targetHeight = maxHeight;
                    targetWidth = Math.round(maxHeight * (originWidth / originHeight));
                }

                log('超過400x400的限制,圖片大小限制爲' + [targetWidth, targetHeight].join('x'));
            } else {
                log('圖片尺寸較小,不壓縮');
            }

            canvas.width = targetWidth;
            canvas.height = targetHeight;

            // 清除畫布
            context.clearRect(0, 0, targetWidth, targetHeight);

            // 圖片壓縮
            context.drawImage(img, 0, 0, targetWidth, targetHeight);

            log('圖片blob二進制形式ajax上傳,當前進度<span id="percent"></span>');
            // 轉爲blob並上傳
            canvas.toBlob(function (blob) {
                // 圖片ajax上傳
                var xhr = new XMLHttpRequest();
                // 顯示進度的元素
                var elePercent = document.getElementById('percent');
                // 上傳文件名
                var filename = encodeURIComponent(file.name).replace(/%/g, '');

                // 上傳中
                xhr.upload.addEventListener("progress", function(e) {
                    elePercent.innerHTML = Math.round(100 * e.loaded / e.total) / 100 + '%';
                }, false);

                // 文件上傳成功或是失敗
                xhr.onreadystatechange = function(e) {
                    if (xhr.readyState == 4) {
                        if (xhr.status == 200) {
                            // 100%進度
                            elePercent.innerHTML = '100%';

                            // 顯示上傳成功後的圖片地址
                            var response = xhr.responseText;

                            if (/^http/.test(response)) {
                                //response = response.split(filename)[0] + filename;
                                log('圖片上傳成功,地址是:<a href="'+ response +'" target="_blank">'+ response +'</a>');
                            } else {
                                log(response);
                            }
                        }
                    }
                };

                // 開始上傳
                xhr.open("POST", '?upload=img', true);
                xhr.setRequestHeader("X_FILENAME", filename);
                xhr.send(blob);
            }, file.type || 'image/png');
        };

        // 文件base64化,以便獲知圖片原始尺寸
        reader.onload = function(e) {
            // 圖片尺寸
            img.src = e.target.result;
        };
        eleFile.addEventListener('change', function (event) {
            file = event.target.files[0];

            if (file.type.indexOf("image") == 0) {
                log('已選擇圖片'+ file.name +',大小爲'+ Math.round(1000 * file.size / (1024*1024)) / 1000 +'M。');

                reader.readAsDataURL(file);
            } else {
                log('選擇的文件非圖片,到此爲止。');
            }
        });
    }
</script>
</body>
</html>

效果圖(canvas壓縮圖片會失真):php

參考:html

php canvas 前端JS壓縮,獲取圖片二進制流數據並上傳前端

https://www.cnblogs.com/-mrl/p/8708114.htmlhtml5

js+php如何實現上傳圖片

https://www.jianshu.com/p/b7f5a706d7daajax

千萬級流量H5應用涉及到的技能點-2:附件上傳以及雲存儲

http://www.imwinlion.com/archives/49canvas

HTML5 file API加canvas實現圖片前端JS壓縮並上傳wordpress

http://www.zhangxinxu.com/wordpress/2017/07/html5-canvas-image-compress-upload/this

相關文章
相關標籤/搜索