在使用 JavaScript 上传之前将图像大小减小到 200kb 不起作用

问题描述 投票:0回答:1

我想在将图像上传到服务器之前将图像大小减小到 200kb。我有 5 个不同的输入来选择 5 个文件。我尝试使用以下代码,但仍然没有运气。我的图像仍然按原样上传(原始尺寸)。请帮助我。谢谢。 这是我到目前为止尝试过的代码:

<div class="col-sm-6">  
<label class="form-label"><strong>ID Proof Front Photo:</strong></label>
<img src="" alt="No Image" id="img1" style='height:150px; display:none;'>                       
<button type="button" id="uploadFrontID" class="registerBtn" onblur="validateIDCardType(), validateFileTypeFront()" onclick="validateIDCardType(), selectFile('frontIDProof')"><img width="35" height="24" src="<?php echo $url; ?>assets/images/id1.svg">  <strong>Select Photo</strong></button>
<input type='file' id="frontIDProof" name="uploadIDFrontPhoto" onchange="readURL1(this)"  style="display:none" accept="image/*" required />
<span id="photoFrontSpan" class="errSpan"></span>
</div>

<div class="col-sm-6">  
<label class="form-label"><strong>ID Proof Back Photo:</strong></label>
<img src="" alt="No Image" id="img2" style='height:150px; display:none;'>
<button type="button" id="uploadBackID" class="registerBtn" onblur="validateFrontID(), validateIDCardType(), validateFileTypeBack()" onclick=" validateIDCardType(), selectFile('backIDProof')"><img width="35" height="24" src="<?php echo $url; ?>assets/images/id2.svg">  <strong>Select Photo</strong></button>
<input type='file' id="backIDProof" name="uploadIDBackPhoto" style="display:none" onchange="readURL2(this)" accept="image/*" required />
<span id="photoBackSpan" class="errSpan"></span>
</div>

<div class="col-sm-6">  
<label class="form-label"><strong>Profile Photo 1:</strong></label>
<img src="" alt="No Image" id="img3" style='height:150px; display:none;'>                           
<button type="button" id="profilePhoto1" class="registerBtn" onblur=" validateProfilePhoto1FileType()" onclick="selectFile('profilePhotoFile1')"><img width="24" height="24" src="<?php echo $url; ?>assets/images/photo1.svg">  <strong>Select Photo</strong></button>
<input type='file' onchange="readURL3(this)" id="profilePhotoFile1" name="uploadPhoto1" style="display:none" accept="image/*" required />
<span id="photoSpan1" class="errSpan"></span>                                   
</div>

<div class="col-sm-6">  
<label class="form-label"><strong>Profile Photo 2:</strong></label>
<img src="" alt="No Image" id="img4" style='height:150px; display:none;'>                           
<button type="button" id="profilePhoto2" class="registerBtn" onblur="validateProfilePhoto2FileType()" onclick="selectFile('profilePhotoFile2')"><img width="24" height="24" src="<?php echo $url; ?>assets/images/photo2.svg">  <strong>Select Photo</strong></button>
<input type='file' id="profilePhotoFile2" onchange="readURL4(this)" name="uploadPhoto2" style="display:none" accept="image/*"/>
<span id="photoSpan2" class="errSpan"></span>
</div>

<div class="col-sm-6">  
<label class="form-label"><strong>Profile Photo 3:</strong></label>
<img src="" alt="No Image" id="img5" style='height:150px; display:none;'>                           
<button type="button" id="profilePhoto3" class="registerBtn" onblur="validateProfilePhoto3FileType()" onclick="selectFile('profilePhotoFile3')"><img width="24" height="24" src="<?php echo $url; ?>assets/images/photo3.svg">  <strong>Select Photo</strong></button>
<input type='file' id="profilePhotoFile3" name="uploadPhoto3" onchange="readURL5(this)" style="display:none" accept="image/*"/>
<span id="photoSpan3" class="errSpan"></span>
</div>

  <script>
  //Image resize code starts

        function selectFile(inputId) {
            document.getElementById(inputId).click();
        }
        
        function compressImage(file, maxSizeKB, callback) {
            const reader = new FileReader();
            reader.onload = function(event) {
                const img = new Image();
                img.onload = function() {
                    const canvas = document.createElement('canvas');
                    const ctx = canvas.getContext('2d');
                    
                    // Set the canvas dimensions to the image dimensions
                    canvas.width = img.width;
                    canvas.height = img.height;
                    
                    // Draw the image on the canvas
                    ctx.drawImage(img, 0, 0);
                    
                    let compressedFile;
                    let scaleFactor = 0.9; // Initial scale factor
                    
                    do {
                        // Compress the image as JPEG by default
                        let dataUrl = canvas.toDataURL('image/jpeg', 0.7);
                        
                        // If the file type is PNG, compress as PNG format
                        if (file.type === 'image/png') {
                            const pngDataUrl = canvas.toDataURL('image/png');
                            
                            // Check if the PNG version is smaller than the JPEG version
                            if (pngDataUrl.length < dataUrl.length) {
                                dataUrl = pngDataUrl;
                            }
                        }
                        
                        // Calculate the file size
                        const fileSizeKB = Math.round(dataUrl.length / 1024);
                        
                        // Check if the file size is within the desired range
                        if (fileSizeKB <= maxSizeKB) {
                            compressedFile = dataUrl;
                            break;
                        }
                        
                        // Reduce dimensions for further compression
                        scaleFactor *= 0.9; // Reduce dimensions by 10%
                        
                        // Adjust canvas dimensions
                        canvas.width *= scaleFactor;
                        canvas.height *= scaleFactor;
                        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
                    } while (scaleFactor > 0.1); // Stop when scale factor is too low
                    
                    // Callback with the compressed image
                    callback(compressedFile);
                }
                img.src = event.target.result;
            }
            reader.readAsDataURL(file);
        }
        
        // Example usage:
        function handleFileInput(inputId, event) {
            const file = event.target.files[0];
            const maxSizeKB = 200; // Maximum file size in KB
            
            // Compress the file
            compressImage(file, maxSizeKB, function(compressedFile) {
                // Do something with the compressed file, like displaying it
                const img = document.createElement('img');
                img.src = compressedFile;
                document.body.appendChild(img);
            });
        }
        
        // Add onchange event listeners to file inputs
        document.getElementById('frontIDProof').addEventListener('change', function(event) {
            handleFileInput('frontIDProof', event);
        });
        document.getElementById('backIDProof').addEventListener('change', function(event) {
            handleFileInput('backIDProof', event);
        });
        document.getElementById('profilePhotoFile1').addEventListener('change', function(event) {
            handleFileInput('profilePhotoFile1', event);
        });
        document.getElementById('profilePhotoFile2').addEventListener('change', function(event) {
            handleFileInput('profilePhotoFile2', event);
        });
        document.getElementById('profilePhotoFile3').addEventListener('change', function(event) {
            handleFileInput('profilePhotoFile3', event);
        });
  
  //Image resize code ends  
  
  function readURL1(input) {
    if (input.files && input.files[0]) {
    
      var reader = new FileReader();
      reader.onload = function (e) { 
        document.querySelector("#img1").setAttribute("src",e.target.result);
      };

      reader.readAsDataURL(input.files[0]); 
      document.getElementById("img1").style.display = "block";
    }
  }
  
    function readURL2(input) {
    if (input.files && input.files[0]) {
    
      var reader = new FileReader();
      reader.onload = function (e) { 
        document.querySelector("#img2").setAttribute("src",e.target.result);
      };

      reader.readAsDataURL(input.files[0]); 
      document.getElementById("img2").style.display = "block";
    }
  }
  
    function readURL3(input) {
    if (input.files && input.files[0]) {
    
      var reader = new FileReader();
      reader.onload = function (e) { 
        document.querySelector("#img3").setAttribute("src",e.target.result);
      };

      reader.readAsDataURL(input.files[0]); 
      document.getElementById("img3").style.display = "block";
    }
  }
  
    function readURL4(input) {
    if (input.files && input.files[0]) {
    
      var reader = new FileReader();
      reader.onload = function (e) { 
        document.querySelector("#img4").setAttribute("src",e.target.result);
      };

      reader.readAsDataURL(input.files[0]); 
      document.getElementById("img4").style.display = "block";
    }
  }
  
    function readURL5(input) {
    if (input.files && input.files[0]) {
    
      var reader = new FileReader();
      reader.onload = function (e) { 
        document.querySelector("#img5").setAttribute("src",e.target.result);
      };

      reader.readAsDataURL(input.files[0]); 
      document.getElementById("img5").style.display = "block";
    }
  }
  
    function enableDisableButton() {
    if (document.getElementById('terms').checked == 0) {
      document.getElementById('regBtn').disabled = true;
    } else {
      document.getElementById('regBtn').disabled = false;
    }
  }
  
  </script>
javascript html image
1个回答
0
投票

在搜索这个时我遇到了这个例子:

    const compressImage = async (file, { quality = 1, type = file.type }) => {
        // Get as image data
        const imageBitmap = await createImageBitmap(file);

        // Draw to canvas
        const canvas = document.createElement('canvas');
        canvas.width = imageBitmap.width;
        canvas.height = imageBitmap.height;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(imageBitmap, 0, 0);

        // Turn into Blob
        const blob = await new Promise((resolve) =>
            canvas.toBlob(resolve, type, quality)
        );

        // Turn Blob into File
        return new File([blob], file.name, {
            type: blob.type,
        });
    };

    // Get the selected file from the file input
    const input = document.querySelector('.my-image-field');
    input.addEventListener('change', async (e) => {
        // Get the files
        const { files } = e.target;

        // No files selected
        if (!files.length) return;

        // We'll store the files in this data transfer object
        const dataTransfer = new DataTransfer();

        // For every file in the files list
        for (const file of files) {
            // We don't have to compress files that aren't images
            if (!file.type.startsWith('image')) {
                // Ignore this file, but do add it to our result
                dataTransfer.items.add(file);
                continue;
            }

            // We compress the file by 50%
            const compressedFile = await compressImage(file, {
                quality: 0.5,
                type: 'image/jpeg',
            });

            // Save back the compressed file instead of the original file
            dataTransfer.items.add(compressedFile);
        }

        // Set value of the file input to our new files list
        e.target.files = dataTransfer.files;
    });

https://pqina.nl/blog/compress-image-before-upload/

这会在特定类的输入发生更改事件时压缩图像。您可以将

compressImage
替换为您的,确保一切兼容,更改
compressImage
调用的参数化并确保正确处理函数的返回,然后每当为此类输入选择文件时,它会自动压缩,因此当您提交表单时,它已经选择了压缩文件而不是原始文件。

你还做了很多代码重复,比如

    function readURL5(input) {
    if (input.files && input.files[0]) {
    
      var reader = new FileReader();
      reader.onload = function (e) { 
        document.querySelector("#img5").setAttribute("src",e.target.result);
      };

      reader.readAsDataURL(input.files[0]); 
      document.getElementById("img5").style.display = "block";
    }
  }

而不是你可以拥有

    function readURL(input, id) {
    if (input.files && input.files[0]) {
    
      var reader = new FileReader();
      reader.onload = function (e) { 
        document.querySelector("#" + id).setAttribute("src",e.target.result);
      };

      reader.readAsDataURL(input.files[0]); 
      document.getElementById(id).style.display = "block";
    }
  }

然后像

readURL(this, "img5")
这样称呼它,然后你就可以拥有一个
readURL
函数而不是 5 个函数,从长远来看,这会对你有很大帮助。

© www.soinside.com 2019 - 2024. All rights reserved.