网站上传图片,预览图片,加载图片的实现方法:
19.4.28
4.28更新:
对于4.27提出的想法现在出现一个问题:利用canvas重绘图像后上传时,移动端与pc端得到的图片效果完全不相同,这对于以移动端为主导的网站简直是致命的,例如:原因如下
canvas不是矢量图,而是像图片一样是 位图模式的。如果不做 Retina屏适配的话,例如二倍屏,浏览器就会以2个像素点的宽度来渲染一个像素,该canvas在Retina屏幕下相当于占据了2倍的空间,相当于图片被放大了一倍,因此图片会变模糊。
因此,要做Retina屏适配,关键是知道当前canvas的实际渲染倍率,然后将canvas放大到该倍率来绘制,最后将canvas压缩成一倍的物理大小来展示。
需要注意的是,canvas中的线条大小、文字大小等都需要乘以该倍率来进行绘制。
canvas的实际渲染倍率
在浏览器的window变量中有一个devicePixelRatio的属性,该属性表示了屏幕的设备像素比,即用几个(通常是2个)像素点宽度来渲染1个像素。
在canvas context中也存在一个 webkitBackingStorePixelRatio 的属性,该属性的值决定了浏览器在渲染canvas之前会用几个像素来来存储画布信息。在iOS6下的safari中的值是2,但是在chrome和iOS7的safari中的值却是1。在iOS6下的safari中,如果有一张100 × 100像素的图片绘制,该图片首先会在内存中生成一张200 × 200的图片,然后再浏览器渲染时会按100 × 100的图片来显示,因此不会出现模糊失真的情况。而在在chrome和iOS7的safari中就会出现模糊。
但是webkitBackingStorePixelRatio属性在各浏览器厂商的获取方式不一样,所以需要加上浏览器前缀来实现兼容。
如下:
var canvas = document.getElementById(“canvas”),
context= canvas.getContext(“2d”);
// 屏幕的设备像素比
var devicePixelRatio = window.devicePixelRatio || 1;
// 浏览器在渲染canvas之前存储画布信息的像素比
var backingStoreRatio = context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
// canvas的实际渲染倍率
var ratio = devicePixelRatio / backingStoreRatio;
之后使用的时候,将canvas宽高设置为:
canvas .width = canvas .width.ratio;
canvas .height = canvas .height.ratio;
对了通过canvas.style.width或canvas.style.height 设置是同canvas .width不同的
要设置canvas的画布大小,使用的是canvas.width 和 canvas.height;
要设置画布的实际渲染大小,使用的style或CSS设置的 width 和height,只是简单的对画布进行缩放。
譬如:
canvas的实际大小的640px × 800px,但是实际渲染到页面的大小是320px × 400px,相当于缩小一倍来显示。
因此,如果要利用canvas显示在屏幕上,且大小不变的话,就是要将canvas放大到设备像素比来绘制(保证清晰度),最后将canvas压缩成一倍的物理大小来展示(保证大小)。如下:
canvas.width = canvas.width * ratio;
canvas.height = canvas.height * ratio;
点这里看看一些设备的devicePixelRatio
(我在自己华为手机上以及pc上测试backingStoreRatio的值都是1)
改后效果: