2022-06-14 Canvas画布模糊问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022-06-14 Canvas画布模糊问题相关的知识,希望对你有一定的参考价值。
参考技术A 【重要】view大小(属性值决定最终上屏时的缩放比例) 画布bufffer大小 gl.viewPort视口大小(映射画布坐标到NDC坐标 -1到1 GL世界的坐标)所有view单位 和 buffer单位不一致的,都要 渲染引擎提供处理的。
renderer = new THREE.WebGLRenderer( antialias: true );
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(screenCanvas.clientWidth, screenCanvas.clientHeight);
json文件内为view单位,创建buffer用的物理像素,绘制通过render 给定dstR 做映射,实现了view单位到物理像素单位的映射。
void Animation::render(SkCanvas* canvas, const SkRect* dstR)
const SkRect srcR = SkRect::MakeSize(this->size());
if (dstR)
canvas->concat(SkMatrix::MakeRectToRect(srcR, *dstR, SkMatrix::kCenter_ScaleToFit));
要自己手动调整和映射。canvas.scale
如何解决画布模糊问题 https://opendocs.alipay.com/support/01rb86
画布大小、图片绘制尺寸、保存图片实际尺寸。viewsize、buffersize。
https://zhuanlan.zhihu.com/p/80852438
https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_canvas_height_width_clear
<!DOCTYPE html>
<html>
<body>
<img src="https://www.w3schools.com/graphics/pic_the_scream.jpg" id="tupian">
<canvas id="myCanvas" width="200" height="200" style="width:200px;height:200px;border:1px solid">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
var c = document.getElementById("myCanvas");
var pixelRatio = 2;
c.width = 200 * pixelRatio;
c.height = 200 * pixelRatio;
var ctx = c.getContext("2d");
//ctx.scale(pixelRatio, pixelRatio)
var img = document.getElementById("tupian");
ctx.drawImage(img, 10, 10);
ctx.fillStyle = "#92B901";
ctx.fillRect(50, 50, 100, 100);
ctx.font = "30px Arial";
ctx.fillText("Hello World"+pixelRatio, 10, 50);
</script>
<button onclick="clearCanvas()">Clear canvas</button>
</body>
</html>
前端css尺寸px是逻辑像素呀,并且window.innerWidth也会逻辑像素。在做threejs的适配是,没有单独设置 canvas.width(决定物理像素) ,而是修改的 canvas.style= width: width + "px", (决定虚拟像素) 。 如果不设置 width 的话,默认 canvas.width = canvas.style.width * pixleRadio 。 适配threejs没有设置width,所以要传递给devicePixelRatio 给threejs 让他内部自己换算到物理物理像素。screenCanvas.clientWidth == viewWidth; viewWidth = getIntValue(viewWidth, w); bufferWidth = getIntValue(bufferWidth, w);
这样的话,绘制接口的坐标 可以走CSS(虽然绘制API单位是物理像素,但是threejs内部有canvas.scale的设置,保证了可以走CSS单位)
如果需要自己调整画布大小呢,用于降级,则可以,自己给定一个devicePixelRatio值,并手动设置canvas.width 和 renderer.setPixelRatio 。
renderer = new THREE.WebGLRenderer( antialias: true );
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(screenCanvas.clientWidth, screenCanvas.clientHeight);
skottie的流程是
view大小(属性值决定最终上屏时的缩放比例) 画布bufffer大小 gl.viewPort视口大小(映射画布坐标到NDC坐标 -1到1 GL世界的坐标)
ViewPort指定坐标比画布buffer大时,绘制超出画布buffer,走Per-Sample_Processing 相关的流程 做裁剪。 Early Fragment Test 可能是有 被剔除
前端html中定义tag的宽高,映射到native决定了自身view的大小和宽高radio。
surface画布物理大小在内存降级时,可以自己降低scale屏幕密度值来减少内存占用,但是要保持radio。
如果radio不一致,则会存在拉伸,在上屏时,由系统根据View的宽高属性,拉伸画布。
在一块很大的画布上,居中绘制,则可以通过glviewport来实现的。
但是如何保持让2d绘制依然使用 逻辑像素单位呢,主要为了生成顶点作用用的。
void Animation::render(SkCanvas* canvas, const SkRect* dstR)
const SkRect srcR = SkRect::MakeSize(this->size());
if (dstR)
canvas->concat(SkMatrix::MakeRectToRect(srcR, *dstR, SkMatrix::kCenter_ScaleToFit));
以上是关于2022-06-14 Canvas画布模糊问题的主要内容,如果未能解决你的问题,请参考以下文章