解决Canvas画图清晰度问题

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

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

在完成开发之后,发现了一个问题,后端返回的图片信息是比较清晰的,当我在前端渲染的时候,将窗口放在扩展屏上时,图像显示正常,但将窗口移入到电脑屏时就出现了模糊现象。
经查资料,最终找到了这个API:Window.devicePixelRatio 返回当前显示设备的物理像素分辨率与CSS 像素分辨率之比。此值也可以解释为像素大小的比率:一个 CSS 像素的大小与一个物理像素的大小。简单来说,它告诉浏览器应使用多少屏幕实际像素来绘制单个 CSS 像素。

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

将窗口移入扩展屏前后 devicePixelRatio 值的对比:
在这里插入图片描述
根据上述描述:缩放倍率 = 物理像素 / CSS像素

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

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宽高。

let mqString = `(resolution: ${window.devicePixelRatio}dppx)`;

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

updatePixelRatio();

matchMedia(mqString).addListener(updatePixelRatio);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/300220.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL练习-DDL语法练习

文章目录 1、数据库操作2、表操作3、DDL数据类型 突然想起来好久没写过SQL了,写一下SQL练习一下😊 个人写sql比较喜欢用小写😁 什么是DDL:DDL是对数据库和表的操作 在这里练习DLL的时候先不添加约束,后面会把约束集中…

YOLOv8模型yaml结构图理解(逐层分析)

前言 YOLO-V8(官网地址):https://github.com/ultralytics/ultralytics 一、yolov8配置yaml文件 YOLOv8的配置文件定义了模型的关键参数和结构,包括类别数、模型尺寸、骨架(backbone)和头部(hea…

迟到的总结:回望 2023 年,期盼 2024 新机会、新挑战

🔭 嗨,您好 👋 我是 vnjohn,在互联网企业担任 Java 开发,CSDN 优质创作者 📖 推荐专栏:Spring、MySQL、Nacos、RocketMQ,后续其他专栏会持续优化更新迭代 🌲文章所在专栏…

2023湾区产城创新大会:培育数字化供应链金融新时代

2023年12月26日,由南方报业传媒集团指导,南方报业传媒集团深圳分社主办的“新质新力——2023湾区产城创新大会”在深圳举行。大会聚集里国内产城研究领域的专家学者以及来自产业园区、金融机构、企业的代表,以新兴产业发展为议题,…

Proteus 各版本安装指南

Proteus下载链接 https://pan.baidu.com/s/1vHgg8jK9KSHdxSU9SDy4vQ?pwd0531 1.鼠标右击【Proteus8.15(64bit)】压缩包(win11及以上系统需先点击“显示更多选项”)【解压到Proteus8.15(64bit) 】。 2.打开解压后的文件夹&#…

FastDFS安装与测试

目录 目标 版本 环境 官方文档 相关概念 安装FastDFS 启动FastDFS 关闭FastDFS 重启FastDFS 用命令测试上传文件 用命令测试下载文件 用命令测试删除文件 用HTTP的方式访问FastDFS中的文件 用HTTP的方式访问FastDFS中的文件整体流程 目标 在Linux服务器上搭建单…

遇见未来的你——感谢你带给我的感悟

目录 一、背景介绍二、思路&方案三、过程1.都说有的人出生就在罗马而有的人却用一辈子都在去向罗马的路上1.1.物质:1.2.精神: 2.做事情要看大再看细3.心存善念,常怀感恩,从小事做起4.所谓的面子在母爱面前像是一粒微尘5.讲道理…

React 中条件渲染的 N 种方法

本文作者系360奇舞团前端开发工程师 条件渲染在React开发中非常重要的功能,它允许开发人员根据条件控制渲染的内容,在创建动态和交互式用户界面方面发挥着至关重要的作用,本文总结了常用的的条件渲染方法。 1.If-else if-else是一种控制流程的…

qt自定义控件的封装

刚学了一个很有意思的东西,前面学了list,Tree,Table三大控件和一部分常用基础控件,但感觉没啥意思,就是用别人的直接用,刚学了一个自定义控件的封装,流程如下: 想把两个不相关的组件封装在一块,直接用ui不行,所以先新添加了qt设计师页面,新添加了一个SmallWidget *ui 在smal…

SLURM作业管理系统之3种作业提交方式

文章目录 前言定义基本概念三种作业提交模式1. 批处理作业(采用 sbatch 命令提交)2. 交互式作业提交(采用 srun 命令提交)3. 分配模式作业(采用 salloc 命令提交) 管理节点部署Slurm常用命令 前言 在高性能…

unity 游戏开发中傻傻分不清URP、HDRP和SRP

文章目录 **URP (Universal Render Pipeline)**:**HDRP (High Definition Render Pipeline)**:**区别**: Unity的URP(Universal Render Pipeline)和HDRP(High Definition Render Pipeline)都是基于SRP(Scri…

k8s yaml文件pod的生命周期

Pod是k8s中最小限额资源管理组件,也是最小化运行容器化的应用的资源管理对象。 Pod是一个抽象的概念,可以理解为一个或者多个容器化应用的集合。 在一个pod当中运行一个容器是最常用的方式。 在一个pod当中同时运行多个容器,在一个pod当中…

2024阿里云服务器可用区选择方法

阿里云服务器地域和可用区怎么选择?地域是指云服务器所在物理数据中心的位置,地域选择就近选择,访客距离地域所在城市越近网络延迟越低,速度就越快;可用区是指同一个地域下,网络和电力相互独立的区域&#…

Strict MIME type checking is enforced for module scripts per HTML spec.

目录 前言错误信息如下:前言 最近使用docker打包Nginx和vue 为镜像文件,启动镜像时报错 错误信息如下: index89886.js:1 Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Stri…

labelme的安装

首先尝试在(openmmlab)的python3.8的环境下安装(失败)。应该是我环境其他部分不对,和python版本应该没什么关系。(后续,创建新的环境后成功,可直接看最后一部分。) 首先安装是没问题的 pip in…

Linux文件操作命令(touch、cat、more、cp、mv、rm)

之前我们学习了对目录(即文件夹的操作,那么现在我们来一起看一下怎么操作文件吧) 1.touch命令 功能:创建文件 语法:touch 参数 参数:被创建的文件路径 注意:touch命令无选项,参…

智能合约:3分钟开发ERC20 token(2)

0.前言 上一节我们讲到了开发智能合约的准备工作,以及在线编程平台remix 智能合约(1) 这一节讲解如何开发、发行一个代币,并具备包括代币铸造mint,转账transfer和销毁burn功能,并确保合约拥有者owner的权限…

autodl学术加速

今天使用autodl加载预训练BERT模型失败,在官方文档里面找到了官方给的代理使用方法。 直接在bash输入: 开启学术加速: source /etc/network_turbo取消学术加速: unset http_proxy && unset https_proxy据说是只能访问这…

计算机组成原理 I/O方式

I/O 方式 I/O方式分类: 程序查询方式。由 CPU通过程序不断查询 /O 设备是否已做好准备,从而控制0 设备与主机交换信息程序中断方式。只在 I/0 设备准备就绪并向 CPU发出中断请求时才予以响应。DMA方式。主存和 I/O 设备之间有一条直接数据通路,当主存和…

【动态规划】【滑动窗口】C++算法:100154 执行操作后的最大分割数量

作者推荐 【动态规划】【字符串】扰乱字符串 本文涉及的基础知识点 C算法:滑动窗口总结 动态规划 LeetCode100154 执行操作后的最大分割数量 给你一个下标从 0 开始的字符串 s 和一个整数 k。 你需要执行以下分割操作,直到字符串 s 变为 空&#xf…