在容器内显示图片的五种方案:contain、cover、fill、none、scale-down

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 前端西瓜哥

大家好,我是前端西瓜哥。今天我们来学习使用 canvas 技术实现图片查看器需要掌握的一个知识点。

需要在一个特定大小的容器内加载并展示一张照片,我们可以怎样进行图片的默认展示?

image.png

contain

contain,将图片保持宽高比缩放到刚好能够放入容器,是最常用的方案。

优点是可以一次看到整张图片,缺点是不能填充整个容器,因此会产生 “黑边”。

这里我们假设画布宽高为 400 x 200,图片宽高为 80 x 80。

先看看示例的模板代码。

const canvas = document.querySelector('canvas');
canvas.width = 400;
canvas.height = 200;
const ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, canvas.width, canvas.height); // 填充黑色底色
const img = new Image();
img.src = './watermelon.jpg'; // 图片大小为 80x80
img.onload = showImg;
function showImg() {
  // 这里选择了 “contain” 方案
  const scale = calcContainScale(img.width, img.height, canvas.width, canvas.height);
  const w = img.width * scale; // 图片缩放后的宽度
  const h = img.height * scale; // 图片缩放后的高度
  const {x, y} = calcPos(w, h, canvas.width, canvas.height) // 顺便让图片居中
  ctx.drawImage(img, x, y, w, h);
}
// 计算让图片居中需要设置的 x,y
function calcPos(w, h, cw, ch) {
  return {
    x: (cw - w) / 2,
    y: (ch - h) / 2
  };
}

我们的 calcContainScale() 方法实现为:

/**
 * contain 模式
 * @param {number} w 图片宽度
 * @param {number} h 图片高度
 * @param {number} cw 容器宽度
 * @param {number} ch 容器高度
 * @returns {number} 缩放比
 */
function calcContainScale(w, h, cw, ch) {
  const scaleW = cw / w;
  const scaleH = ch / h;
  const scale = Math.min(scaleW, scaleH); // 取小值
  return scale;
}

算法很简单:计算出将图片的宽高分别缩放为容器宽高需要的比例,然后取其中小的即可。

原因很简单,如果你取大的,必然导致另一个长度超过容器尺寸,图片无法被装下。

image.png

cover

cover,图片保持宽高比并尽可能充满容器,需要图片的宽缩放为容器宽,或图片的高缩放为容器宽,然后多余的内容截断。

优点是可以用最小的缩放比来填充容器所有的地方,缺点是不能展示图片所有的内容。

function calcCoverScale(w, h, cw, ch) {
  const scaleW = cw / w;
  const scaleH = ch / h;
  const scale = Math.max(scaleW, scaleH); // 取大值
  return scale;
}

和 contain 相反,算出将图片的宽高分别缩放为容器宽高需要的比例之后,要取其中的大值。

因为我们是要尽可能填充容器,另一个边如果超出了容器范围,就将其截断。

image.png

fill

fill,图片完全填充容器,不要求保持宽高比,可以对图片进行拉伸。

非常少用,因为会将图片拉伸,导致图片非常难看。

实现上,只要直接将图片的宽高设置为容器的宽高即可,不需要用到什么计算。

ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

image.png

none

none,图片保持原本大小、不进行缩放地显示。

ctx.drawImage(img, x, y, img.width, img.height);

image.png

scale-down

scale-down,应用 contain 和 none 中图片尺寸较小的。

这么做是希望尺寸小于容器的图片能保持原比例,而不是被放大导致失真。

function calcScaleDownScale(w, h, cw, ch) {
  const scaleW = cw / w;
  const scaleH = ch / h;
  const scale = Math.min(scaleW, scaleH, 1); // 比例不能小于 1
  return scale;
}

图片尺寸远小于容器,最终选择是 none 的方式。

image.png

总结

西瓜哥我总结一下这 5 种图片填充容器的方式:

1.contain:刚好完整放入容器,不多也不少;2.cover:充满容器,但尺寸尽量小;3.fill:不保持宽高比,直接拉伸填充容器;4.none:保持图片最初的模样;5.scale-down:如果可以不放大就能放入容器,直接放入(none);如果不能,就放大点,让其刚好放入容器(contain)

相关文章
|
Cloud Native 虚拟化 云计算
《Docker基础知识解析:容器与虚拟化的区别与优势,选择最佳方案优化云计算应用》
《Docker基础知识解析:容器与虚拟化的区别与优势,选择最佳方案优化云计算应用》
434 0
|
监控 安全 Cloud Native
容器安全的风险应对及 Twislock 容器安全方案| 学习笔记
快速学习容器安全的风险应对及 Twislock 容器安全方案。
容器安全的风险应对及 Twislock 容器安全方案| 学习笔记
|
存储 边缘计算 数据管理
Docker 存储驱动解析:选择最适合你的存储方案,优化容器化部署性能和数据管理
Docker 存储驱动解析:选择最适合你的存储方案,优化容器化部署性能和数据管理
360 0
|
2月前
|
Kubernetes API Docker
跟着iLogtail学习容器运行时与K8s下日志采集方案
iLogtail 作为开源可观测数据采集器,对 Kubernetes 环境下日志采集有着非常好的支持,本文跟随 iLogtail 的脚步,了解容器运行时与 K8s 下日志数据采集原理。
|
3月前
|
移动开发 小程序 前端开发
跨端技术演进问题之Web容器方案在跨端开发中的优势和不足如何解决
跨端技术演进问题之Web容器方案在跨端开发中的优势和不足如何解决
|
5月前
|
Docker 容器
蓝易云 - Docker修改容器ulimit的全部方案及各方案的详细步骤
以上就是修改Docker容器ulimit的全部方案及其详细步骤。
258 2
|
6月前
|
弹性计算 安全 微服务
【阿里云云原生专栏】容器网络技术前沿:阿里云Terway网络方案详解
【5月更文挑战第26天】阿里云Terway是高性能的容器网络方案,基于ECS的ENI实现,提供低延迟高吞吐的网络服务。它简化网络管理,实现安全隔离,并与阿里云服务无缝集成。Terway由CNI、Node和Controller组成,适用于微服务、混合云和多租户环境,为企业数字化转型中的复杂网络需求提供强大支持。
390 1
|
Kubernetes 调度 Apache
Docker 编排工具比较:Kubernetes、Docker Swarm 和 Mesos,选择最适合你的容器编排方案
Docker 编排工具比较:Kubernetes、Docker Swarm 和 Mesos,选择最适合你的容器编排方案
368 0
|
6月前
|
Java 应用服务中间件 API
【SpringBoot技术专题】「开发实战系列」Undertow web容器的入门实战及调优方案精讲
【SpringBoot技术专题】「开发实战系列」Undertow web容器的入门实战及调优方案精讲
187 0
|
6月前
|
Web App开发 安全 前端开发
百度搜索:蓝易云【Docker WebRTC容器部署方案】
以上是一个简单的Docker WebRTC容器部署方案。在实际应用中,你可能需要根据自己的需求进行更复杂的配置和优化。此外,要确保你的WebRTC应用程序在Docker容器中能够正确运行,可能需要处理一些网络和安全方面的问题。
159 6