天天看點

php canvas 前端JS壓縮,擷取圖檔二進制流資料并上傳,OK

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

<?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" rel="external nofollow" 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>