此篇记录一下图片传输的学习笔记,也顺便带大家了解~
上传图片
首先建立一个上传图片的 input
// 加上 multiple 可上传多个档案<input type="file" name="file" id="file" multiple>
上传档案后可以用 files
属性抓出资料
我们可以观察到他是 FileList,并不是阵列,且里面有档名、类型、大小等等的详细资料,接下来读取档案有两种方法,分别是 Blob URL
与 FileReader
,以下分开介绍
Blob URL
当我们拿到 FileList 后可以使用 URL.createObjectURL()
方法将图片转为 Blob URL
const file = document.querySelector('#myfile').files[0]URL.createObjectURL(file)// blob:http://127.0.0.1:5500/f0c69bbc-e8d7-4ba8-aaf2-ab8ab794da28
我们拿到的 Blob URL
是指向当前记忆体位址,也就是说可以直接在网址输入并检视图片
上传图片预览
我们亦可使用 Blob URL
来直接实现图片预览功能
首先新增一个 img
供预览图片用
<input type="file" name="file" id="file"><img id="img">
接下来设定监听事件,在上传时将图片显示出来
const myFile = document.querySelector('#file')myFile.addEventListener('change', function(e) { const file = e.target.files[0] const img = document.querySelector('#img') img.src = URL.createObjectURL(file)})
下载图片
当然我们也可以使用 Blob URL
来下载自己上传的图片
我们改写一下刚刚监听的内容
const myFile = document.querySelector('#file')myFile.addEventListener('change', function(e) { const file = e.target.files[0] // 创造一个 a 标籤 const downloadLink = document.createElement('a') // 将 a 标籤的连结改为 Blob URL downloadLink.href = URL.createObjectURL(file) // 将下载的档名设定为 file downloadLink.download = 'file' // 点击标籤 downloadLink.click()})
如此一来上传的同时也下载了图片
FileReader
再来介绍另一个方法,FileReader
可以将档案转成各种格式
readAsText()
readAsDataURL()
: 转换成 Base64 编码readAsArrayBuffer()
readAsBinaryString()
const myFile = document.querySelector('#file')myFile.addEventListener('change', function(e) { // 取得档案 const file = e.target.files[0] // 宣告 FileReader const reader = new FileReader() // 进行格式转换 // 档案转换完成后执行 reader.onload = function() { // 可以用 reader.result 查看编译结果 console.log(reader.result) }})
基本宣告方法皆相同,只差在转换的格式不同,接下来就介绍一下格式
Text
Text
预设使用 UTF-8
的编码,将档案转换成文字
DataURL ( Base64 )
DataURL
使用 Base64 直接将图片编码,因此档案大小越大,编码长度也就越长,不过他与 Blob URL
不同,因为不是记忆体位址,所以可以将图片绘出,且同样可以做到预览图片与下载的功能
<input type="file" name="file" id="file"><img id="img">
const myFile = document.querySelector('#file')myFile.addEventListener('change', function(e) { const file = e.target.files[0] const reader = new FileReader() // 转换成 DataURL reader.readAsDataURL(file) reader.onload = function() { // 将图片 src 替换为 DataURL img.src = reader.result }})
也同样能实现下载功能
const myFile = document.querySelector('#file')myFile.addEventListener('change', function(e) { const file = e.target.files[0] const reader = new FileReader() // 转换成 DataURL reader.readAsDataURL(file) reader.onload = function() { // 创造一个 a 标籤 const downloadLink = document.createElement('a') // 将 a 标籤的连结改为 DataURL downloadLink.href = reader.result // 将下载的档名设定为 file downloadLink.download = 'file' // 点击标籤 downloadLink.click() }})
ArrayBuffer
ArrayBuffer
是一种原始二进制数据,可再将其编译成 Blob
const myFile = document.querySelector('#file')myFile.addEventListener('change', function(e) { const file = e.target.files[0] const reader = new FileReader() // 转换成 ArrayBuffer reader.readAsArrayBuffer(file) reader.onload = function() { // 将 ArrayBuffer 转成 Blob // 后方 type 可填入需要的类型 const blob = new Blob([reader.result], { type: 'image/jpeg' }) // 亦可将 Blob 再次转成 Blob URL console.log(URL.createObjectURL(blob)) }})
亦可直接将 ArrayBuffer
编译为 DataURL
const myFile = document.querySelector('#file')myFile.addEventListener('change', function(e) { const file = e.target.files[0] const reader = new FileReader() // 转换成 ArrayBuffer reader.readAsArrayBuffer(file) reader.onload = function() { // 将 ArrayBuffer 转换为 字串 const str = String.fromCharCode.apply(null, new Uint8Array(reader.result)) // 将其组成 DataURL console.log('data:image/jpg;base64,' + btoa(str)) }})
BinaryString
BinaryString
已经被 W3C 弃用,所以不建议使用
canvas
图片与 canvas 可以互相转换,如果不知道 canvas 是甚么的话可以参考这边
图片转 canvas
不管是 Blob URL
还是 DataURL
都可以将其转成 canvas 绘製,首先我们先建立一个 canvas,然后使用 drawImage
方法将其绘製出来,使用之前介绍的 Blob URL
或是 DataURL
方法皆可
<input type="file" name="file" id="file"><canvas id="mycanvas"></canvas>
Blob URL
const myFile = document.querySelector('#file')const canvas = document.getElementById('mycanvas')const ctx = canvas.getContext('2d')myFile.addEventListener('change', function(e) { const file = e.target.files[0] // 宣告一个新图片 let img = new Image() img.src = URL.createObjectURL(file) img.onload = function() { // 设定 canvas 宽高等同图片 canvas.width = img.width canvas.height = img.height // 将其绘製,并设定绘製的图片宽高 ctx.drawImage(img, 0, 0, img.width, img.height) }})
DataURL
const myFile = document.querySelector('#file')const canvas = document.getElementById('mycanvas')const ctx = canvas.getContext('2d')myFile.addEventListener('change', function(e) { const file = e.target.files[0] const reader = new FileReader() // 转换成 DataURL reader.readAsDataURL(file) reader.onload = function() { // 宣告一个新图片 let img = new Image() // 将图片 src 替换为 DataURL img.src = reader.result img.onload = function() { // 设定 canvas 宽高等同图片 canvas.width = img.width canvas.height = img.height // 将其绘製,并设定绘製的图片宽高 ctx.drawImage(img, 0, 0, img.width, img.height) } }})
canvas 转图片
首先我们绘製一个 canvas
<canvas id="mycanvas" width="150" height="150"></canvas><img id="img">
const canvas = document.getElementById('mycanvas')const ctx = canvas.getContext('2d')canvas.width = 150canvas.height = 150ctx.fillRect(25, 25, 100, 100)
接下来使用 toDataURL
方法可将其转为 DataURL
const img = document.getElementById('img')const data = canvas.toDataURL('image/png')img.src = data
转换后也可使用上面学过的的功能下载唷!
canvas 转 Blob
可以用 toBlob
的方法将其转为 Blob
canvas.toBlob(function(blob) { console.log(blob)})
canvas 转 Uint8ClampedArray
同上先画出 canvas 图形,使用 getImageData
可以获取 Uint8ClampedArray
的数据
ctx.getImageData(0, 0, 150, 150).data
其实图片的处理就是各种编码的转换,只要熟悉各种资料类型与处理方式,就可以简单的操控图片啰!