解决Canvas画图清晰度问题

最近在开发Web端远程桌面的时候遇到的一个问题,解决记录一下,分享给各位有需要用到的朋友。

先吹下水:远程桌面的连接我们是通过Websocket连接后,后端不断返回远程端的界面二进制数据流,我接收到之后转为图像,画到Canvas中,然后对canvas进行一系列的事件监听,传递消息给服务端,从而实现远程桌面的连接操作。

在完成开发之后,发现了一个问题,后端返回的图片信息是比较清晰的,当我在前端渲染的时候,将窗口放在扩展屏上时,图像显示正常,但将窗口移入到电脑屏时就出现了模糊现象。

经查资料,最终找到了这个API:Window.devicePixelRatio 返回当前显示设备的物理像素分辨率与CSS 像素分辨率之比。此值也可以解释为像素大小的比率:一个 CSS 像素的大小与一个物理像素的大小。简单来说,它告诉浏览器应使用多少屏幕实际像素来绘制单个 CSS 像素。

物理像素的大小即是在内存中的实际大小,CSS像素的大小即是设置的样式大小。

将窗口移入扩展屏前后 devicePixelRatio 值的对比:

根据上述描述:缩放倍率 = 物理像素 / CSS像素

当我们设置图像在canvas中的实际大小的时候,不要直接将物理像素等于样式像素,而是要设置等于样式像素乘以缩放倍率。

javascript 复制代码
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// 假设获取到的图片宽是600,高是400
const width = 600, height = 400;
// 设置canvas的样式宽高
canvas.style.width = width + "px";
canvas.style.height = height + "px";

// 设置物理像素,在内存中的实际大小
var scale = window.devicePixelRatio; // 获取缩放倍率
canvas.width = Math.floor(width * scale);
canvas.height = Math.floor(height * scale);

// 绘图
ctx.drawImage('图片信息', 0, 0, canvas.width, canvas.height)

当缩放倍率改变时,例如屏幕大小改变等,我们可以使用监听缩放倍率来实现更新canvas宽高。

javascript 复制代码
let mqString = `(resolution: ${window.devicePixelRatio}dppx)`;

const updatePixelRatio = () => {
  let pr = window.devicePixelRatio;
  // 更新业务逻辑代码
};

updatePixelRatio();

matchMedia(mqString).addListener(updatePixelRatio);
相关推荐
xm_xm_xm_115 分钟前
react17版本以前类组件常用操作
前端·javascript·react.js
lzhdim2 小时前
13、JavaScript事件循环机制 - JavaScript学习系列文章
开发语言·前端·javascript·学习·ecmascript
liangshanbo12152 小时前
Vue 3 <script setup> 的本质原理是什么?它与普通 setup()有何区别?
前端·javascript·vue.js
七牛开发者4 小时前
实测推荐 3 个 Skill,轻松上手 Codex 网页设计与交付流程
前端·javascript·后端
七牛开发者4 小时前
拆解 dsh 系列:从源码和版本变化看 DeepSeek Harness 的设计取舍
前端·javascript·后端
谭光志4 小时前
如何从网站提取设计风格:DOM、计算样式与 DESIGN.md
前端·javascript·agent
柒和远方5 小时前
V079: Milvus 向量数据库:AI 日记本的三组件部署、集合字段建模与余弦索引
javascript·sql
水獭比特5 小时前
Anthropic Files / Skills 迁移:Workspace 不是租户隔离,API Key 也不是用户身份
javascript
默_笙5 小时前
☕ 我给 TS 类型做了台"瘦身手术",还顺手用 Docker 起了个 MySQL
前端·javascript
ji_shuke6 小时前
Vue 3 使用 History 哨兵和 popstate 拦截浏览器返回
前端·javascript·vue.js·history·哨兵·popstate