binary

  • ArrayBuffer
  • TypedArray
  • DataView
  • Character &&base64 conversion
  • FileReader && Blob/File conversion
  • File && Blob conversion
  • Bolb
  • DataURL(Base64) &&ojecturl usage
  • Canvas upload, comprehensive application
    • ImageData => Canvas application
    • Canvas => imageData application
  • Express photo upload service

The images cover various transformations of streams. Here are some examples. If you need them, go down to the examples below

Binary conversion

  • Integer part: mod by 2 until the quotient is 0. The remainder first obtained is the lowest and the remainder last is the highest
  • Fractional part: multiply by 2 and round until the product is 0 or precision requires, the first integer to be high
  • 10 = (11.1) 2 (3.5)
  • Source code: binary number,3 bits can represent 8 numbers +0+1+2+3-0-1-2-3,4 positive 4 negative (the highest digit 1 is a negative number,0 is a positive number)
  • Inverse code: the positive number is unchanged, the negative number except for the sign of all the other digits
  • Complement: Positive numbers remain the same, negative numbers are added to the inverse code by 1(the highest bits should be dropped)
  • The computer only has one kind of complement, the complement of positive number + other negative number =0, the computer calculates through the complement
  // Negative complement + positive complement = 0

  // Negative number positive number
  // Source code 1 001011 0 001011
  // Reverse code 1 110100 1 110101
  // Complement 1 110101

  // 4 + (-4) = 0
  / / 00100 + 10100
  // 00100 + 11011
  // 00100 + 11100(complement)
Copy the code

ArrayBuffer(basic)

  • 8 bits == 1 byte, and an ArrayBuffer (each of which is 8 bits) contains bytes
// 8 bytes x 8 bits = 64 bits
let buffer = new ArrayBuffer(8)
Copy the code

TypedArray Type data

let buffer = new ArrayBuffer(8);// 8 bytes of ArrayBuffer
const int8Array = new Int8Array(buffer)// An integer takes up 8 bits
console.log(int8Array.length)// The length of the element is 8,1 byte occupies 8 bits

console.log(int8Array.buffer === buffer)// true

const int16Array = new Int16Array(buffer)// An integer takes up 16 bits
console.log(int16Array.length)// element length 4,1 byte occupies 16 bits
Copy the code

The DataView object

  • The DataView view is a low-level interface that can read and write multiple numeric types from a binary ArrayBuffer object
  • SetInt8 () stores an 8-bit number (one byte) from the specified byteOffset at the start of the DataView
  • GetInt8 () retrieves an 8-bit number (one byte) from the specified byteOffset at the DataView starting position
  • Buffers are referenced within both DataView and TypeArray. Buffers cannot be used directly

const buffer = new ArrayBuffer(8);
// Create an 8-byte arrayBuffer
console.log(buffer.byteLength);/ / 8 bytes
const view1 = new DataView(buffer);
// The first integer is 8 bytes and the value is 1
view1.setInt8(0.1); // 0 is the starting place to store 1
console.log(view1.getInt8(0));/ / 1
// The second integer is 8 bytes and the value is 1
view1.setInt8(1.2); // 1 is the start place to skip 8 bytes and store 2
// The binary bit 0000 0010 is 2 when the second byte is read
console.log(view1.getInt8(1));/ / 2

// When reading 16 bits, concatenate the top two bits to get 258
console.log(view1.getInt16(0));/ / 258

console.log(view1.buffer === buffer)
Copy the code

Character &&base64 conversion

  • window.btoa && window.atob
    • It’s stored on window
    • Btoa is wide to convert a string toa base64
    • Atob converts Base64 to a string
let rs =  btoa('xxx')
// rs is a base64 string

let s = atob(rs)
// atob converts base64 to string s===' XXX '
Copy the code

FileReader && Blob/File conversion

  • FileReader function, read Blob, he has three ways to read, respectively generated ArrayBuffer, Base64 string, text
  • ReadAsArrayBuffer generates an ArrayBuffer
  • ReadAsDataURL generates a Base64 string
  • What readAsText generates is it generates a text
function readBlob(blob,type){
  return new Promise((resolve) = >{
    let reader = new FileReader()
    reader.onload = function(event){
      resolve(event.target.result)
    }
    switch(type){
      case 'ArrayBuffer':
      // readAsArrayBuffer generates an ArrayBuffer
        reader.readAsArrayBuffer(blob);
        break;
      case 'DataURL':
      // The binary data is converted to a readable string base64 string
        reader.readAsDataURL(blob);
        break;
      case 'Text':
      // A text is generated
        reader.readAsText(blob,'utf-8');
        break;
      default:
        break;
    }
  })
}
readBlob(blob,'ArrayBuffer').then(rs= >{
  console.log('ArrayBuffer',rs)
})
readBlob(blob,'DataURL').then(rs= >{
  console.log('DataURL',rs)
})
readBlob(blob,'Text').then(rs= >{
  console.log('Text',rs)
})
Copy the code

File && Blob conversion

Blob=>File

  • usage
var file = new File([blob], "foo.png", {
  type: "image/png"});Copy the code

Blob=>File

let blob = new Blob([file],{
    type:'image/png'
})
Copy the code

Blob

  • File transfer, upload and download, all in Blob format
  • Blob function
  • Constructor var aBlob = new Blob(array, options);
    • An array is an array made up of objects like ArrayBuffer, ArrayBufferView, Blob, DOMString(JS String), or a mixture of similar objects that will be put into the Blob. DOMStrings will be encoded to UTF-8.
    • Options is an optional BlobPropertyBag dictionary
    • The default value of type is “”, which represents the MIME type of the array content to be put into the BLOB

OjectURL

  • URL.createObjectURL
    • You can get a memory URL for the current file
    • Use DOMString to generate a BLOB file to download as JSON
// DOMString
function download(){
    let data = 'xxxxx'
    let blob = new Blob([data],{type:'application/json'})
    let a = document.createElement('a')
      a.download = 'user.json'/ / download
      a.rel = 'noopener'
      a.href = URL.createObjectURL(blob)
      a.dispatchEvent(new MouseEvent('click'));
      URL.revokeObjectURL(blob);// Destroying objectURL also destroys the Blob
    console.log(blob,URL.createObjectURL(blob))
  }
Copy the code
  • Download by uploading pictures
<input type="file" onchange="handleChange(event)">
<button onclick="download()">download</button>

<script>
  function download(data){
  let bytes = new ArrayBuffer(data.length)
  let arr = new Uint8Array(bytes)
  for(let i=0; i<data.length; i++){ arr[i] = data.charCodeAt(i) }let blob = new Blob([arr],{type:'image/png'})
  let a = document.createElement('a')
    a.download = 'user.png'/ / download
    a.rel = 'noopener'
    // a.href = blob;
    a.href = URL.createObjectURL(blob)
    a.dispatchEvent(new MouseEvent('click'));
    URL.revokeObjectURL(blob);// Destroying objectURL also destroys the Blob
}
  function handleChange(e){
    let file = null;
    file = e.target.files[0];
    let fileReader = new FileReader()
      fileReader.onload = e= >{
        // ATOB is a global method
        // Base64 must be converted to characters
        let bytes = atob(e.target.result.split(', ') [1])
        download(bytes)
      }
      fileReader.readAsDataURL(file)
  }
</script>
Copy the code

DataURL

  • Base64 string

Blob generation DataURL

  • DataURL is wide enough to be used directly by imc.src
function readBlob(blob,type){
  return new Promise((resolve) = >{
    let reader = new FileReader()
    reader.onload = function(event){
      resolve(event.target.result)
    }
    switch(type){
      case 'ArrayBuffer':
      // readAsArrayBuffer generates an ArrayBuffer
        reader.readAsArrayBuffer(blob);
        break;
      case 'DataURL':
      // The binary data is converted to a readable string base64 string
        reader.readAsDataURL(blob);
        break;
      case 'Text':
      // A text is generated
        reader.readAsText(blob,'utf-8');
        break;
      default:
        break;
    }
  })
}
readBlob(blob,'ArrayBuffer').then(rs= >{
  console.log('ArrayBuffer',rs)
})
readBlob(blob,'DataURL').then(rs= >{
  console.log('DataURL',rs)
})
readBlob(blob,'Text').then(rs= >{
  console.log('Text',rs)
})
Copy the code

Input How to convert uploaded files (images, XLSX, etc.) into arrays

  • The FileReader function, which has three ways of reading, is generated separatelyArrayBuffer.Base64 string.The text
  • Input Upload file is a Blob
function readBlob(blob,type){
  return new Promise((resolve) = >{
    let reader = new FileReader()
    reader.onload = function(event){
      resolve(event.target.result)
    }
    switch(type){
      case 'ArrayBuffer':
      // readAsArrayBuffer generates an ArrayBuffer
        reader.readAsArrayBuffer(blob);
        break;
      case 'DataURL':
      // The binary data is converted to a readable string base64 string
        reader.readAsDataURL(blob);
        break;
      case 'Text':
      // A text is generated
        reader.readAsText(blob,'utf-8');
        break;
      default:
        break;
    }
  })
}
readBlob(blob,'ArrayBuffer').then(rs= >{
  console.log('ArrayBuffer',rs)
})
readBlob(blob,'DataURL').then(rs= >{
  console.log('DataURL',rs)
})
readBlob(blob,'Text').then(rs= >{
  console.log('Text',rs)
})
Copy the code
  • Basr64 => ArrayBuffer => blob, download the image
  <input type="file" onchange="handleChange(event)">
  <button onclick="download()">download</button>


  <script>
    function download(data){
    let bytes = new ArrayBuffer(data.length)
    let arr = new Uint8Array(bytes)
    for(let i=0; i<data.length; i++){ arr[i] = data.charCodeAt(i) }let blob = new Blob([arr],{type:'image/png'})
    let a = document.createElement('a')
      a.download = 'user.png'/ / download
      a.rel = 'noopener'
      // a.href = blob;
      a.href = URL.createObjectURL(blob)
      a.dispatchEvent(new MouseEvent('click'));
      URL.revokeObjectURL(blob);// Destroying objectURL also destroys the Blob
  }
    function handleChange(e){
      let file = null;
      file = e.target.files[0];
      let fileReader = new FileReader()
        fileReader.onload = e= >{
          // ATOB is a global method
          // Base64 must be converted to characters
          let bytes = atob(e.target.result.split(', ') [1])
          download(bytes)
        }
        fileReader.readAsDataURL(file)
    }
  </script>
Copy the code

Blob converts base64 or image

  • URL.createObjectURL
  • reader.readAsDataURL
  <input type="file" onchange="handleChange(event)">
  <img src=' ' id='img'>
  <script>
  function handleChange(e){
    let file = null;
    file = e.target.files[0];
    let url = URL.createObjectURL(file)
    img.src=  url
  }

  function handleChange(e){
    let file = null;
    file = e.target.files[0];
    let fileReader = new FileReader()
      fileReader.onload = e= >{
        img.src = e.target.result
        console.log(img.src)
      }
      fileReader.readAsDataURL(file)
  }
  </script>
Copy the code

Canvas

ImageData => Canvas application

Canvas => imageData application

  • Picture screenshot upload is carried out according to the API above
<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Document</title>
  <style>
    body{
      display: flex;
    }
    .div1 img{
      border: 2px dashed green;
      width: 500px;
    }
    .div1{
      display: flex;
      width: 500px;
      flex-wrap: wrap;
    }
  </style>
</head>
<body>
    <div class="div1">
        <input type="file" accept="image/*" onchange="handleChange(event)">
        <img src="" alt="" id='img'>
    </div>

    <style>
      .div2{
        margin-left: 50px;
        position: relative;
      }
      #can{
        border: 2px dashed blue;
      }
      .divCenter{
        position: absolute;
        width: 100px;
        height: 100px;
        background: yellow;
        opacity: 0.3;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        margin: auto;
      }
    </style>

    <div class="div2" onmousedown="handleMouseDown(event)" onmousemove="handleMouseMove(event)" onmouseup="handleMouseUp(event)">
      <canvas
        id="can"
        width="300px"
        height="300px"
      ></canvas>
      <div class="divCenter"></div>
      <div class="btn-group">
        <button type="button" onclick="bigger()">bigger</button>
        <button type="button" onclick="smaller()">smaller</button>
        <button type="button" onclick="confirm()">clip</button>
      </div>
    </div>

    <div class="div3">
      <img width="100px" src="" alt="" id='img1'>
      <button onclick="upload()">upload</button>
    </div>
    <script>
      let state = {
        timer:1.// Magnification
        startX:0.// Mouse down start X coordinates
        startY:0.startDrag:false.// Start dragging
        lastX:0.// The last mouse lift
        lastY:0.avatarDataURL:' '
      }
      let img = document.querySelector('#img')
      let img1 = document.querySelector('#img1')
      let can = document.querySelector('canvas')
      upload = () = >{
        Base64 format: type +,+ data
        // Only base64 data can be processed when atOB transforms
        let bytes = atob(state.avatarDataURL.split(', ') [1])

        let arrayBuffer = new ArrayBuffer(bytes.length)
        let uint8Array = new Uint8Array(arrayBuffer);
        for(let i=0; i<bytes.length; i++){ uint8Array[i] = bytes.charCodeAt(i) }let blob = new Blob([uint8Array],{type:'image/png'.ss:'xxx'});
        let xhr = new XMLHttpRequest
        let formData = new FormData();
        formData.append('avatar',blob)
        xhr.open('POST'.'http://localhost:4000/upload'.true);
        xhr.send(formData);
      }
      
      bigger = () = >{
        state.timer +=0.1 
        drawImage()
      }
      smaller = () = >{
        state.timer -=0.1 
        drawImage()
      }
      confirm = (event) = >{
        let ctx = can.getContext('2d')
        // Copies the pixel data of the specified rectangle on the canvas
        // canvas => imageData
        const imageData = ctx.getImageData(100.100.100.100)
        let avatar =  document.createElement('canvas')
        avatar.width =100
        avatar.height= 100
        let avatarCtx = avatar.getContext('2d');
        // Then put the image data back onto the canvas with putImageData()
        // imageData => canvas
        avatarCtx.putImageData(imageData,0.0)
        // base64
        let avatarDataURL = avatar.toDataURL()
        state.avatarDataURL = avatarDataURL
        img1.src = avatarDataURL
      }
      handleMouseDown = (event) = >{
        state.startX = event.clientX
        state.startY = event.clientY
        state.startDrag = true
      }
      handleMouseMove = (event) = >{
        // X mimics the quantity that moves in the Y direction
        if(state.startDrag)
        drawImage(
          event.clientX-state.startX+state.lastX,
          event.clientY-state.startY+state.lastY  )
      }
      handleMouseUp = (event) = >{
        state.startDrag = false
        state.lastX = event.clientX - state.startX +state.lastX
        state.lastY = event.clientY - state.startY +state.lastY
      }
      drawImage = (left=state.lastX,top=state.lastY) = >{
        let ctx = can.getContext('2d')
        ctx.clearRect(0.0,can.width,can.height)
        let imageWidth = img.width
        let imageHeight = img.height
        if(imageWidth>imageHeight){// If the width ratio reaches the width of the image, adjust to the canvas width
          let scale = can.width/imageWidth
          imageWidth = can.width*state.timer
          imageHeight = can.height*scale*state.timer
        }else{
          let scale = can.height/imageHeight
          imageHeight = can.height*state.timer
          imageWidth = can.width*scale*state.timer
        }
        / / draw pictures
        ctx.drawImage(img,(can.width-imageWidth)/2+left,(can.height-imageHeight)/2+top,imageWidth,imageHeight)
      }

      function handleChange(e){
        let file = e.target.files[0];
        let fileReader = new FileReader()
        fileReader.onload = e= >{
          img.src = e.target.result
          // Execute the callback to draw canvas after the image loads successfully
          img.onload=() = >drawImage()
        }
        fileReader.readAsDataURL(file)
      }
    </script>
</body>
</html>
Copy the code

The background

  • express
// Image upload
let express = require('express');
let multer = require('multer')
let fs = require('fs')
let cors = require('cors');
let path = require('path')
let app = express();
// Process the request body in JSON format
app.use(express.json());
// Process the request body in form format
app.use(express.urlencoded({ extended: true }));
app.use(cors());
// File upload req.file Stream for obtaining the file dest req.file Directory for saving the file
let upload = multer({ upload: 'upload/' })

app.post('/post'.(req, res) = > {
  let body = req.body
  console.log(body)
  res.send(body)
})
app.post('/form'.(req, res) = > {
  let body = req.body
  res.send(body)
})
// Use upload.single('avatar') for only one file type
app.post('/upload', upload.single('avatar'), (req, res) = > {
  // req.file Specifies the type of data stored in the file
  // Req. body contains the usual type of data
  if (req.file) {
    let rs = '. '+req.file.mimetype.match(/. + \ / (. +) /) [1]
	console.log('rs', req.file);
	console.log('req.file.originalname', req.file.originalname);
    fs.writeFileSync(path.join(__dirname, ` /${req.file.fieldname}${rs}`), req.file.buffer)
  }
  res.send(req.body)
})

// xls
app.post('/xls', upload.single('avatar'), (req, res) = > {
  if (req.file) {
    fs.writeFileSync(path.join(__dirname, ` /${req.file.fieldname}.xls`), req.file.buffer)
  }
  res.send(req.body)
})

app.listen(4000)
Copy the code