mapbox中添加图片addImage看似简单的一个方法,但是在实际的生产过程当中却产生了不少的问题,好比如何加载本地图片。这个一个小问题能够来回搞了好久,如今来看多種加载方式是如何实现的:canvas
HTMLImageElement服务器
let image = new Image(64, 64); // 这里的imageUrl采用require方式调用的base64格式 image.src = imageUrl; image.onload = () =>{ this.map.addImage("custom-marker", image); };
ImageBitmap异步
ImageBitmap接口表示一个位图图像,能够在WebGL中高效绘制。能够使用函数 createImageBitmap 建立,异步加载ide
// 这里的imageData采用require方式调用的base64格式 //createImageBitmap方法支持的数据格式有<img>, SVG <image>, <video>, <canvas>, HTMLImageElement, SVGImageElement, HTMLVideoElement, HTMLCanvasElement, Blob, ImageData, ImageBitmap, or OffscreenCanvas object.这里使用Blob window.createImageBitmap(this.b64toBlob(imageData), 0, 0, 64, 64).then(res => { this.map.addImage("custom-marker", res); }); function b64toBlob(dataURI) { var byteString = atob(dataURI.split(",")[1]); var ab = new ArrayBuffer(byteString.length); var ia = new Uint8Array(ab); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ab], { type: "image/jpeg" }); }
ImageData函数
canvas对象的像素数据,能够使用构造器
ImageData()
建立,也能够用canvas渲染上下文中createImageData()
方法建立ui
/** @HTMLCanvasElement */ var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); let image = new Image(64, 64); image.src = image_Base64; image.onload = () => { ctx.drawImage(image, 0, 0); this.map.addImage('custom-marker', ctx.getImageData(0,0,64,64)); };
{width: number, height: number, data: (Uint8Array | Uint8ClampedArray)}this
与ImageData相似code
StyleImageInterface对象
mapbox内部定义的image渲染接口,经常使用于动态渲染接口
var flashingSquare = { width: 64, height: 64, data: new Uint8Array(64 * 64 * 4), onAdd: function(map) { this.map = map; }, render: function() { // keep repainting while the icon is on the map this.map.triggerRepaint(); // alternate between black and white based on the time var value = Math.round(Date.now() / 1000) % 2 === 0 ? 255 : 0; // check if image needs to be changed if (value !== this.previousValue) { this.previousValue = value; var bytesPerPixel = 4; for (var x = 0; x < this.width; x++) { for (var y = 0; y < this.height; y++) { var offset = (y * this.width + x) * bytesPerPixel; this.data[offset + 0] = value; this.data[offset + 1] = value; this.data[offset + 2] = value; this.data[offset + 3] = 255; } } // return true to indicate that the image changed return true; } } }; map.addImage("flashing_square", flashingSquare);
比较这几种方式,HTMLImageElement
是最经常使用的方式,也是最简单的方式(须要注意这里的Image须要base64的文件,或者服务器上的文件路径);后面的ImageBitmap
, ImageData
, 经常使用于canvas渲染中使用,StyleImageInterface
是mapbox内置的一种动态渲染接口。