获取网络图片
一般地,每个网络上的图片都对应有一个远程的地址,我们称之为:URL,即我们通常说的网页地址,根据我们获取图片的目的不同,我们一般可以分为两种方式来获取图片:
-
获取图片直接展示
展示图片一般使用:<img src="http://localhost/path/to/picture.png" alt="示例图片">
-
当需要编辑和保存图片、或某些图片URL不支持get请求时
但是某些情况下,我们获取待获取的图片可能并不支持直接使用http-get
的方式进行,也有可能由于安全性或其他方面的原因,后端要求图片获取必须使用http-post
的方式获取,并且根据post
的body
来区分不同的图片,那么此时就无法直接使用上述方式获取并展示图片了。-
<img id='img' alt="待预览的图片"> <script> async function loadpic(url,body){ const res = await windows.fetch(url,{ method:"POST", body:body }); const picBlob = await res.blob(); //doSomething with picBlob const docUrl = URL.createObjectURL(picBlob); document.querySelector("#img").src = docUrl; } loadpic('http://localhost/path/to',{name:'picture.png'}); </script>
-
async function loadpic(url,body){ const xhr = new XMLHttpRequest(); return new Promise((resolve,reject)=>{ xhr.addEventListener('load',function(event){ resolve(xhr. response); }); xhr.open("POST", url); xhr.send(body); }) }
-
获取本地图片
通过input[type=file]
获取图片
<input onchange="inputChange()" type="file" style="visibility:hidden" id="picker">
<button onclick="startPick()">选择图片</button>
<script>
function inputChange({target:{files}}){
//files的类型为FileList对象,其并非数组,因此不能直接通过forEach遍历
[].prototype.forEach.call(files,function(file){
//doSomething with file
});
//获取使用for循环遍历
for(let i=0;i<files.length;i++){
const file = files[i];
//doSomething with file
}
}
function startPick(){
document.querySelector("#picker").click();
}
</script>
图片上传
-
XMLHttpRequest
async function upload(uploadUrl,picBlob){ let xhr = new XMLHttpRequest(); xhr.open("POST",uploadUrl); return new Promise((resolve,reject)=>{ xhr.addEventListener("load",resolve); xhr.addEventListener("error",reject); let form = new FormData(); form.append("pic",picBlob); xhr.send(form); }); }
-
window.fetch
async function upload(uploadUrl,picBlob){ let form = new FormData(); form.append("pic",picBlob); return fetch(uploadUrl,{ method:"POST", body:form }); }
canvas图片获取
canvas.toDataURL(type, encoderOptions)、canvas.toBlob(callback, mimeType, qualityArgument)
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 150, 100);
//图片DabaURL获取
let picDataUrl = canvas.toDataURL();
//图片blob获取
let picBlob;
canvas.toBlob(function(blob){
picBlob = blob;
// window.location = URL.createObjectURL(blob);
})
图片存储
展示图片
-
<img>
展示- URL.resolveDataURL
- dataURL
- URL
-
canvas展示
<canvas id="canvas"> <script> let image = new Image(); image.src=picDataURL; image.onload = function(){ let canvas = document.querySelector("canvas"); canvas.width = image.width; canvas.height = image.height; canvas.getContext('2d').drawImage(image, 0, 0, canvas.width, canvas.height); } </script>
-
扩展:图片大量图片加载时可以用到img的loading属性,它有两个值:
此部分内容由于img[loading]的兼容性问题,不推荐使用,因此删除
part1.png
part2.png
1. eager:默认值,立即加载图片,不管img是否在视窗内
2. lazy:推迟加载图片,直到img在浏览器定义的视窗范围内
-
图片压缩
利用 canvas.toDataURL 进行压缩
async function compress(dataUrl,quality){
let image = new Image();
let result = await new Promise((resolve,reject)=>{
image.src=dataUrl;
image.addEventListener("load",function(){
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
//还可以通过对 canvas.width、canvas.height 的设置,来修改图片的尺寸
canvas.getContext('2d').drawImage(image, 0, 0, canvas.width, canvas.height);
//通过quality来修改图片的质量,注意:只有“image/jpeg” 和 “image/webp” 支持图像品质压缩
//若此处设置输出类型为“image/png”则quality设置无效
let result = canvas.toDataURL('image/jpeg',quality);
canvas = null;
image = null;
resolve(result);
});
})
return result;
}
图片各类型直接转换
-
图片二进制转base64(dataUrl)
<img id="img" alt=""> async function blob2dataUrl(blob){ const reader = new FileReader(); let dataUrl = await new Promise((resolve,reject)=>{ reader.addEventListener('load',resolve); reader.addEventListener('error',reject); reader.readAsDataURL(blob); }); return dataUrl; } document.querySelector("#img").src=blob2dataUrl(imgBlob);
同样的,若
imgBlog
为input.files[0]
,blob2dataUrl(blob)
也能使用 -
base64转图片二进制
根据Data URLs的语法:data:[<mediatype>][;base64],<data>
可以将
Data URLs
拆分为mine-type
以及base64 string
两部分,然后由着两部分构造Blob
对象function dataURLtoBlob(dataurl) { const arr = dataurl.split(','); const mime = arr[0].match(/:(.*?);/)[1]; const binaryStr = atob(arr[1]); //atob:ascii to binary const n = bstr.length const u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new Blob([u8arr], { type: mime }) }
注意:此方法只能针对base64的图片
Data URL
进行转换,因为根据Data URLs
的语法,其并不一定是以base64编码,此时并不适用上述方法进行解析和转换
cordova
特有的图片操作
-
将本地文件路径转换为
FileEntry
window.resolveLocalFileSystemURL('file:///path/to/file',function(fileEntry){ //doSomething with fileEntry; });
resolveLocalFileSystemURL文档
注意:此api并非标准的webapi,因此需要对其兼容性进行处理,在chrome上需要加’webkit-‘前缀,ios版safri本并不支持此api,cordova需要安装 cordova-plugin-file 插件来启用此api的支持
-
由
FileEntry
读取文件fileEntry.file(function (file) { // Do something with file }, onErrorReadFile);
-
将图片写入到手机存储
async function writeFile(filePath,picBlob){ return new Promise((resolve,reject)=>{ window.resolveLocalFileSystemURL(filePath,function(fileEntry){ fileEntry.createWrite(function(writer){ writer.onwriteend = resolve; writer.onerror = reject; writer.write(picBlob); }); }); }); }