简体   繁体   English

调整大小和上传脚本耗时过长

[英]Resize and upload script taking too long

I'm using a script which resizes images client side before uploading them via Ajax to a PHP file.在通过 Ajax 将图像上传到 PHP 文件之前,我正在使用一个脚本来调整图像客户端的大小。 I am resizing images client side to reduce the power demand on the server.我正在调整图像客户端的大小以减少服务器上的电力需求。 My script works but is taking too long to upload the image and I need help understanding why this is the case.我的脚本有效,但上传图像的时间太长,我需要帮助理解为什么会这样。 The first part of the file asynchronously resizes the image.文件的第一部分异步调整图像大小。 The second part encodes the resized image source to dynamically created hidden input and finally, Ajax uploads the dynamically created input value to a PHP file by using a timeout 3-second delay function.第二部分将调整大小的图像源编码为动态创建的隐藏输入,最后,Ajax 通过使用超时 3 秒延迟 ZC1C425268E68385D1AB5074C17A94 将动态创建的输入值上传到 PHP 文件。

$(document).ready(function() {
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });
    /* Upload Logo Image */
    $("#loader-wrapper").hide();
    $("#logo_image").change(function(){

        $("#ImgText").fadeOut(10, "linear");
        $("#loader-wrapper").css('background-image', 'none').fadeIn(200, "linear");

        const form = document.querySelector('#user_update_settings');

        form.addEventListener('change', async (e) => {
        e.preventDefault();

        // Get data URI of the selected image
        const formData = new FormData(e.currentTarget);
        const photoField = formData.get('logo_image');
        const dataUri = await dataUriFromFormField(photoField);

        // Defines Resized image URL
        const imgEl = document.createElement('img');
        imgEl.addEventListener('load', () => {
            const resizedDataUri = resizeImage(imgEl, 600);

                // Deletes Previous Input
                var element =  document.getElementById('new_logo_image');
                if (typeof(element) != 'undefined' && element != null)
                {
                var elementExists = document.getElementById("new_logo_image");
                elementExists.remove();
                } 

                // Creates New Input
                var objTo = document.getElementById('LogoInputContainer')
                var image_input = document.createElement("input");
                image_input.setAttribute("name", "new_logo_image");
                image_input.setAttribute("id", "new_logo_image");
                image_input.setAttribute("type", "hidden");
                image_input.setAttribute("value", resizedDataUri);

                objTo.appendChild(image_input);
                
            });

        imgEl.src = dataUri;

        });

        // Resize Script
        function dataUriFromFormField (field) {
        return new Promise((resolve) => {
            const reader = new FileReader();
            
            reader.addEventListener('load', () => {
            resolve(reader.result);
            });
            
            reader.readAsDataURL(field);
        });
        }

        function resizeImage(imgEl, wantedWidth) {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');

            const aspect = imgEl.width / imgEl.height;

            canvas.width = wantedWidth;
            canvas.height = wantedWidth / aspect;

            ctx.drawImage(imgEl, 0, 0, canvas.width, canvas.height);
            return canvas.toDataURL();
        }
    });

    // Image Upload
 $("#logo_image").change(function(){
    setTimeout(() => {  
        
        if(window.File && window.FileReader && window.FileList && window.Blob){
            if($(this).val()){

            // Checks File Extension
            var fileExtension = ['jpeg', 'jpg', 'png', 'gif', 'bmp'];
            if ($.inArray($(this).val().split('.').pop().toLowerCase(), fileExtension) == -1) {
                alert("Only formats are allowed : "+fileExtension.join(', '));
                exit();
            }

                $.ajax({
                    url: "/logo_uploader",
                    type: "POST",
                    data: new FormData($("#user_update_settings")[0]),
                    contentType: false,
                    cache: false,
                    processData: false,
                    dataType: 'json',
                    success:function(response){
                        if(response.type == 'success'){
                            $("#loader-wrapper").fadeOut();
                            $(".logo_image_container").css("background-image", "url("+ response.logo_image +")");

                        }else{
                            $("#loader-wrapper").fadeOut();
                            $("#ImgText").fadein(10, "linear").text("+ response.msg +");
                        }
                    }
                });
            }
            } else {
                alert("Can't upload! Your browser does not support File API!</div>");
                return false;
            }
        }, 3000);
    });
});

Client-side, my logo uploader validates the file type, deletes the previous image [if it exists] decodes the $request->new_logo_image and saves the file in the folder 'logos' and in a SQL database.在客户端,我的徽标上传器验证文件类型,删除之前的图像 [如果它存在] 解码 $request->new_logo_image 并将文件保存在文件夹 'logos' 和 SQL 数据库中。

// User ID
        $user_id = auth()->user()->id;

        // Reserved Goods
        $user = Users::where('id', $user_id)->first();

        // Path
        $FilePathDB = FilePathDB::first();

        // Path
        $file_path = $FilePathDB->public_img_path;
        $path = $file_path.$user->logo_image;

        // Deletes Previous Logo [If Applicable]
        if(file_exists($path)) {
            File::delete($path);
        }
        
        // Validates Extension
        $validatedData = $request->validate([
            'logo_image' => 'required|image|mimes:jpg,png,jpeg',
        ]);

        // Generates a Unique New Name 
        $new_name = 'logos/'.$user_id.trim($user->username).uniqid().'.jpg';

        // Uploads request Image if file does not exist
        if($request->hasFile('logo_image')) {

            $image =  $request->new_logo_image; // your base64 encoded
            $image = str_replace('data:image/png;base64,', '', $image);
            $image = str_replace(' ', '+', $image);
            File::put($file_path.$new_name, base64_decode($image));


            // Logo Image Variable
            $formFields = array(
                'logo_image' => $new_name
            );

            // User ID Update
            $users = Users::where('id', $user_id)
            ->update($formFields);

                // If Successful
                $response = print json_encode(array(
                    'type'=> 'success',
                    'msg' => 'Logo Uploaded Successfully',
                    'logo_image' => 'storage/'.$new_name,
                ));  
            } else {
                
                // If unsuccessful
                $response = print json_encode(array(
                    'type'=> 'failed',
                    'msg' => 'Ooops, image upload unsuccessful. Please try again!',
                )); 
            }

Condensed HTML浓缩 HTML

<form method="POST" action="/user_update_settings" id="user_update_settings" enctype="multipart/form-data">
<label for="logo_image" class="pointer UploadImgBtn transition">
<input class="DisplayNone" type="file" name="logo_image" id="logo_image" accept="image/*">
<a>Upload Image</a> 
</label>
</form>

On average, for a 3MB image, it takes 3 seconds for JS canvas to resize the image and 15-20 seconds to upload the already resized file - now between 40-50KB in size.平均而言,对于 3MB 的图像,JS canvas 调整图像大小需要 3 秒,上传已经调整大小的文件需要 15-20 秒 - 现在大小在 40-50KB 之间。 Knowing the image has been resized, why does it take so long for my code to upload the resized image?知道图像已调整大小,为什么我的代码需要这么长时间才能上传调整大小的图像? Are there any loops I haven't considered running in the background which are consuming the client's resources?是否有任何我没有考虑在后台运行的循环正在消耗客户端的资源?

After much thinking, I have just found the solution.经过深思熟虑,我刚刚找到了解决方案。 When I ran my Ajax script I was submitting the whole form to the server which included both the old and the new image.当我运行 Ajax 脚本时,我将整个表单提交到服务器,其中包括旧图像和新图像。 To reduce the data load, one can either put the hidden input into a new form or else specify the data which is to be sent to the PHP file.为了减少数据负载,可以将隐藏的输入放入新的表单中,或者指定要发送到 PHP 文件的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM