px — 物理像素,设备屏幕上图像的最小元素。在移动开发中,px被用作屏幕分辨率和像素密度(PPI)的基本单位,但实际上并不用于界面布局——取而代之的是使用逻辑单位pt、dp和sp。本文解释了px与逻辑单位的区别,分辨率和PPI如何关联,以及为什么在代码中直接使用px是一种反模式。
主要内容
px(pixel,picture element)— 位图图像或显示器的最小可寻址元素。每个像素以RGB模型(红、绿、蓝)存储颜色信息,每个通道的颜色深度为8到10位。现代移动设备的显示屏包含数百万像素:iPhone 15 Pro — 300万,iPad Pro 12.9" — 560万像素。
像素的物理尺寸取决于显示密度(PPI)。在326 PPI(iPhone 11)的设备上,一个像素的尺寸约为0.078毫米。在460 PPI(iPhone 15 Pro)的显示屏上 — 0.055毫米。像素的物理尺寸越小,图像的清晰度就越高。像素密度直接影响渲染性能:更多像素 = GPU更多工作量。
根据苹果的数据,iPhone 15 Pro的显示屏分辨率在460 PPI密度下为1179 × 2556 px。相比之下,iPhone SE(第3代)— 750 × 1334 px,326 PPI。总像素数差异近3倍,这解释了Pro型号对GPU的更高要求。
屏幕分辨率 — 水平和垂直方向的物理像素数量。以宽度 × 高度的格式表示,例如 1179 × 2556 px。分辨率是显示器的基本特性,无法通过编程改变——它在硬件和矩阵级别上固定。
| 设备 | 分辨率(px) | PPI | 宽高比 |
|---|---|---|---|
| iPhone SE(第3代) | 750 × 1334 | 326 | 16:9 |
| iPhone 14 | 1170 × 2532 | 460 | 19.5:9 |
| iPhone 15 Pro Max | 1290 × 2796 | 460 | 19.5:9 |
| Samsung Galaxy S24 Ultra | 1440 × 3120 | 505 | 19.5:9 |
| Google Pixel 8 Pro | 1344 × 2992 | 490 | 20:9 |
| iPad Pro 12.9" | 2048 × 2732 | 264 | 4:3 |
像素分辨率不应与屏幕逻辑尺寸混淆(iOS中为pt,Android中为dp)。例如,iPhone 14的逻辑尺寸为390 × 844 pt,但物理分辨率为1170 × 2532 px——正好大3倍,因为缩放因子为3。
PPI(pixels per inch)— 每英寸显示屏上的像素数量。计算公式为:PPI = √(宽度² + 高度²) / 对角线。PPI越高,单个像素越细小,图像看起来越平滑。苹果认为在典型观看距离下PPI超过300的显示屏为Retina显示屏。
不同类别的设备具有不同的密度:Apple Watch手表 — 326 PPI,iPhone — 326–460 PPI,iPad — 264 PPI,MacBook Pro — 254–264 PPI。Android设备通过密度桶(Density Buckets)对密度进行分类:mdpi(160 dpi)、hdpi(240)、xhdpi(320)、xxhdpi(480)、xxxhdpi(640)。这些桶决定了将为设备加载哪个资源(图像、尺寸)。
PPI对开发的影响:密度越高,存储纹理和图像所需的内存就越多。在500 PPI显示屏上的像素,在相同逻辑元素尺寸下,比320 PPI显示屏需要多2.5倍的GPU内存。针对特定密度桶优化资源是Android开发中的标准做法。
物理像素(px)与逻辑单位(pt、dp、sp)不同,因为它们与硬件分辨率绑定且不可缩放。逻辑单位则相反,将开发者从特定显示器中抽象出来,使相同的100 pt值在不同设备上以相同的物理尺寸显示。
| 单位 | 平台 | 取决于PPI | 可缩放 | 用途 |
|---|---|---|---|---|
| px | 所有 | 是(物理像素) | 否 | 图像、缓冲区、Metal |
| pt | iOS/macOS | 否(逻辑点) | 缩放因子 | 布局、UIKit、SwiftUI |
| dp | Android | 否(密度无关) | 密度桶 | 布局、元素尺寸 |
| sp | Android | 否(缩放无关) | 密度 + 字体缩放 | 文本(textSize) |
转换公式:iOS — px = pt × scale(其中scale = 1、2或3)。Android — px = dp × (dpi / 160)。在代码中直接使用px意味着界面在不同密度的设备上会显示不同:在高PPI屏幕上元素会太小,在低PPI屏幕上则太大。
在移动应用程序的源代码中使用px — 是一种反模式,会导致界面在不同像素密度的设备上显示不正确。现代框架(UIKit、SwiftUI、Jetpack Compose、XML Layouts)禁止或不推荐以像素为单位指定尺寸。
在代码中唯一合法的使用px — 处理光栅缓冲区:加载Bitmap、创建Canvas进行图像渲染、使用Metal或OpenGL。在这些情况下,px是目标缓冲区的物理像素,需要加以考虑以确保正确渲染。在所有其他情况下,使用逻辑单位。
图像和图标以像素方式存储,但为每种屏幕类型提供不同版本。iOS在Assets.xcassets中使用@1x、@2x、@3x后缀。Android使用drawable-mdpi(1×)、drawable-hdpi(1.5×)、drawable-xhdpi(2×)、drawable-xxhdpi(3×)、drawable-xxxhdpi(4×)文件夹。系统根据屏幕密度自动选择合适的文件。
| iOS缩放 | Android桶 | 系数 | 示例(48 pt/dp) |
|---|---|---|---|
| @1x | mdpi(160 dpi) | 1× | 48 × 48 px |
| @2x | xhdpi(320 dpi) | 2× | 96 × 96 px |
| @3x | xxhdpi(480 dpi) | 3× | 144 × 144 px |
| — | xxxhdpi(640 dpi) | 4× | 192 × 192 px |
资源提供规则:以矢量格式(PDF、SVG)创建图像,并导出为所需尺寸的光栅副本。矢量资源可无质量损失缩放,且在仓库中占用更少空间。在Android中,矢量资源可通过VectorDrawable直接使用,从而消除了对多个光栅副本的需求。
常见问题
px — 屏幕的物理像素。dp(密度无关像素)— Android的逻辑单位,在密度为160 dpi的屏幕上等于1 px。在不同密度下,dp会自动转换为不同数量的px,同时保持元素的物理尺寸。
因为px不考虑屏幕密度。尺寸为100 px的元素在不同PPI的设备上看起来会不同:在326 PPI的屏幕上会比460 PPI上更大。逻辑单位(dp、pt、sp)会自动解决这个问题。
PPI(pixels per inch)— 每英寸显示屏的像素数量。计算公式为:PPI = √(w² + h²) / d,其中w和h是以px为单位的分辨率,d是以英寸为单位的对角线。PPI越高,图像越清晰。苹果Retina显示屏从300 PPI开始。
px在处理光栅缓冲区时是合理的:创建Bitmap、在Canvas中渲染、Metal/OpenGL着色器编程、相机图像处理。在布局和排印中不使用px——而是使用pt(iOS)、dp和sp(Android)。
在iOS中:UIScreen.main.nativeBounds返回以px为单位的尺寸。在Android中:DisplayMetrics.widthPixels和heightPixels来自context.resources.displayMetrics。在SwiftUI中:GeometryReader返回以pt为单位的尺寸,要获得px需要乘以displayScale。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。