Location>code7788 >text

Image compression is guaranteed to make you look good!

Popularity:233 ℃/2024-08-10 11:23:53

take

Many times, one meets the scenario of image uploading.
Before uploading to the server.
The front-end in order to save storage space on the server.
The image will be compressed.
Let's learn about image compression.
Image compression steps.
1. Select the picture. Use <input type="file"> to realize the
2. Display the selected image. Get the base64 of the picture, and then assign it.
3. Compress the picture, if the compressed picture is larger than the original picture, continue to call the compression function until it is smaller than the original picture (e.g. 30% smaller).

Selecting an image and displaying it

We are reading the file.
Need to restrict the type of image.
Currently we support the formats 'image/png', 'image/jpeg', 'image/gif', 'image/bmp'.
Then we convert the image to base64 encoding.
<style>
  #originPic{
    display: none;
  }
</style>

<div>
  <input type="file" value="Please select an image" accept="image/*"> </div> </style> <div>
</div>.
<div >
  <span> Original image:</span>
  <img src="" >
</div>

<script>
  let fileNode = ('file')
  // The readFile method is triggered when the user selects a file
  ('change', readFile, false)
  // The box that holds the picture
  let originPicNode = ('originPic')
  // The image DOM node
  let originImg = ('originImg')
  // Common image type formats
  let canSelectPicTypeArr = ['image/png', 'image/jpeg', 'image/gif', 'image/bmp']
  function readFile(e){
    // Get the file selected by the user
    let file = [0]
    // Check if the selected image matches the requirements
    if(()){
      // Create a file object
      let reader = new FileReader()
      (file)
      // Once the image has been read, assign the image's src to the img tag
       = function(){
         = function(){
         = 'block'
      }
    }else{
      let str = (',')
      alert('Only image formats are currently supported' + str)
    }
  }
</script>

Compressing images

To compress the image.
We need to create canvas tag, img tag.
Drawing the selected image on the canvas can be done with the help of the function
Finally, the compression is achieved by using the function
(picType, quality)
picType: the type of the image.
quality: the quality of the compression, value range 0-1, default is 0.92, the smaller the value, the bigger the compression.
// We will now start compressing the image
function assetImg(originPicInfo){
  // Create the canvas tag
  let canvasEle = ('canvas')
  // Create the img tag
  let imgEle = ('img')
  // Create the img tag
   =
  // canvas context
  let ctx= ('2d')
  // Read the image
   = ()=>{
    // Get the width and height of the image
    const imgWidth =
    const imgHeight =
    // Set the width and height of the image to the canvas
     = imgWidth
     = imgHeight
    // Draw the image onto the canvas
    (imgEle, 0,0,imgWidth, imgHeight)
    // Generate a compressed image
    const assetPicBase64 = (, 0.7)
    ('Compressed image', assetPicBase64)
  }
}

Why is the image larger than the original after encoding it in base64?

To answer this question, you need to understand the basics of base64 encoding.
Its basic principle is: using 64 basic ASCII characters to re-encode the data.
First of all, he will source code data split byte array.
To 3 bytes as a group, in order to arrange the 24-bit data.
Then the 24-bit data is divided into four groups, that is, each group of 6 bits.
Add two 00s in front of each group to make up one byte.
In this way, a 3-byte group of data is re-encoded into 4 bytes.
[Read this, perhaps you should guess why the image through the base64 encoding than the original picture is larger than the reason].
When the number of bytes of data to be encoded is not an integer multiple of 3.
That is to say, when the last group is not 3 bytes, the last group will be filled with 1 or 2 bytes.
It will fill the last group with 1 or 2 0 bytes.
and add 1 or 2 "=" at the end of the final encoding.
We know from the encoding rules that using Base64 encoding.
The original 3 bytes will become 4 bytes after encoding.
This means that the number of bytes has increased by 33.3% and the amount of data has increased accordingly.
So the size of 31KB data encoded by Base64 is about 31M*133.3%=42KM.
This part of the reference related links:
/blog/2008/06/
/u/1422143/blog/702602

How do I deal with compressed images that are smaller than the original?

We have just learned why the size of a base64 encoded image is larger than the original.
It's because: after 3 bytes are encoded, they become 4 bytes. So it's bigger than the original.
Now we just need to judge the size of the image.
If the compressed image is bigger than the original, continue to call the compression function.
If it is smaller than the original image, stop it. Return the compressed image in base64 format.

Implementation of the image compression function

<style>
  #originPic{
    display: none;
  }
  #assetsBox{
    display: none;
  }
</style>

<div>
  <input type="file" value="Please select a picture" accept="image/*">
</div>
<div >
  <p>original figure:</p>
  <img src="" >
</div>
<div >
  <p>Compressed image:</p>
  <img src="" >
</div>
// The type of the image
let fileType = ''
// Compressed image (base64)
let compressImgSrc = ''
// Compressed quality value
let qualityValue = 0.9
 = ()=>{
  // ... Other core code...
  // Call image compression
  doPicCompress(canvasEle, ,fileType)
  ('Compress', compressImgSrc, qualityValue)
  // Display the compressed image on the page
  if(assetsBox){
     = 'block'
     = compressImgSrc
  }
}

// Implement image compression
function doPicCompress(canvas, imgSrc, type){
  // Convert the image to base64
  compressImgSrc = (type, qualityValue)
  // If the compressed image is larger than the original and the quality of the image can continue to be downgraded, continue compression
  if(>= && qualityValue>0.1){
    // The core of the compression here is downgrading the quality of the image.
    qualityValue = qualityValue - 0.1
    // Continue compression
    doPicCompress(canvas, imgSrc, type)
  }
}


Will the image still be larger than the original after compression several times

Some of you may say.
Just now you said that the image encoded as base64 will be larger than the original.
If it is a relatively small picture (30KB) or so.
Will appear after many compression, the picture is still larger than the original picture of this situation?
Actually, this kind of situation is possible.
The reason is: the image is originally smaller. After encoding base64, it will be bigger than the original image.
With toDataURL compression, it is not necessarily smaller than the original image.
So, if the image is small, the way we compress it with toDataURL is not good.
Of course, after processing the front-end image compression, the back-end can also be compressed.
Here we are through the node plugin to simply look at the following

Using sharp for image compression

sharp:This plugin is mainly used to convert large images in common formats into smaller, more web-friendly images in JPEG, PNG, WebP, GIF and AVIF formats.
JPEG, PNG, WebP, GIF and AVIF formats that are more suitable for web use.
It also allows you to resize images.
Installation: npm install sharp -S
The specific address to use: /package/shap
// Introducing dependencies
const sharp = require('sharp');
// Pass in an image path of . /, compress it, and output the new save
sharp('. /').png({ quality: 50 }).toFile('', (err, info) => {
  if (err) throw err;
  if (info){
    (info);
  }
 }).

All Codes

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8"> <meta name="viewer"> <header>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #originPic{
      display: none;
    }
    #assetsBox{
      display: none; }
    }
  #assetsBox{ display: none; }
</head>
</style> </head> </body>
  <body> <div>
    <input type="file" value="Please select an image" accept="image/*"> </div> </div>
  </div>.
  <div >
    <p> Original image:</p>
    <img src="" >
  </div>.

  <div >
    <p> compressed image:</p>
    <img src="" >
  </div>
</body>
</html>.
<script>.
  let fileNode = ('file')
  // The readFile method is triggered when the user selects a file
  ('change', readFile, false)
  // The box that holds the picture
  let originPicNode = ('originPic')
  // The image DOM node
  let originImg = ('originImg')
  // The DOM node that holds the image after compression
  let assetsBox = ('assetsBox')
  // The DOM node for the compressed image
  let assetsImg = ('assetsImg')
  // Common image type formats
  let canSelectPicTypeArr = ['image/png', 'image/jpeg', 'image/gif', 'image/bmp']
  // The type of the image
  let fileType = ''
  // The compressed image (base64)
  let compressImgSrc = ''
  // Compressed quality value
  let qualityValue = 0.2
  function readFile(e){
    // Get the file selected by the user
    let file = [0]
    fileType =
    // Check to see if a matching image has been selected
    if((fileType)){
      // Create a file object
      let reader = new FileReader()
      (file)
       = function(){
         =
        (, 'Compressed size', )
         = 'block'
        // Call the image compression function
        assetImg({originImgSrc: , quality:0.9, imgType: fileType})
      }
    }else{
      let str = (',')
      alert('Only image formats are currently supported' + str)
    }
  }

  // We'll now start compressing the image
  function assetImg(originPicInfo){
    // Create the canvas tag
    let canvasEle = ('canvas')
    // Create the img tag
    let imgEle = ('img')
     =
    let ctx= ('2d')
    // Read the image
     = ()=>{
      // Get the width and height of the image
      const imgWidth =
      const imgHeight =
      // Set the width and height of the image to the canvas
       = imgWidth
       = imgHeight
      // Draw the image onto the canvas
      (imgEle, 0,0,imgWidth, imgHeight)
      // Call image compression
      doPicCompress(canvasEle, ,fileType)
      (compressImgSrc, qualityValue, 'after compression')
      // Display the compressed image on the page
      if(assetsBox){
         = 'block'
         = compressImgSrc
      }
    }
  }

  // Implement image compression
  function doPicCompress(canvas, imgSrc, type){
    // Convert the image to base64
    compressImgSrc = (type, qualityValue)
    // If the compressed image is larger than the original and the quality of the image can continue to be downgraded, continue compression
    if(>= && qualityValue>0.1){
      // The core of the compression here is downgrading the quality of the image.
      qualityValue = qualityValue - 0.1
      // Continue compression
      doPicCompress(canvas, imgSrc, type)
    }
  }
</script>

coda

If you think my writing is good.
Can you give me a like? Thank you.
Without further ado, today is another day of bug fixing!