MAC 平台retina高分屏开发技术分享

转自:http://guoxiaosi1990.diandian.com/post/2012-07-06/40029975069

版本支持了RETINA,作为国内首个支持RETINA高分屏的MAC OS X APP,我们希望能够和大家分享一些在RETINA支持方面的开发技术心得。欢迎MAC平台的开发朋友们与我们沟通交流。也希望可以通过IBLOG这个平台在今后和大家交流MAC OS X系统方面的技术经验。

基本概念和思想

和iOS的异同

在系统对高分屏的支持上,Mac OS和iOS基本上是一样的:都是两倍的Scale Factor,都是系统自动来完成这个Scaling。但Mac OS毕竟是电脑操作系统,与iOS相比,多了对以下几个方面的支持:

  1. window和screen的关系

  2. 多显示器

  3. 显示器分辨率的随时更改

两种运行模式:Framework-Scaled和Magnified

在高分屏的Mac中,App有两种运行模式: Framework-Scaled模式和Magnified模式。两种模式的差别,在于Backing Store层的大小。什么是Backing Store层?我们的App和显示器之间,其实有一层buffer层,这层就是Backing Store层。在Framework-Scaled模式下,Backing Store层的大小和显示器一样,而Magnified模式时是显示器的四分之一(长宽各为二分之一),相当于同尺寸普通屏的大小。

在Framework-Scaled模式下,因为Backing Store层的大小和显示器一样,所以我们的App可以更精细地做视觉处理。而与之相比,Magnified模式其实是一个纯粹为兼容而设计的模式。在Magnified模式下,因为Backing Store层的大小和普通屏一样,App还是以1x的形式运行,在显示时,即Backing Store层到显示器的转换时,系统再把其拉伸到2x。这样,在Magnified模式下的App会保持和普通屏一致的表现,当然,也会因拉伸而看上去有点模糊。

非Cocoa的App则只能以Magnified模式运行,而Cocoa App默认是以Framework-Scaled模式运行。 如果Cocoa App觉得自己在Framework-Scaled模式下运行有较大体验问题,也可以在程序中将自己设成默认以Magnified模式运行。 此外,用户也可以通过程序文件的“显示简介”窗口手动更改App的运行模式。

毫无疑问,要在高分屏上有细腻的视觉感受,我们的程序必须运行在Framework-Scaled模式下。

Point和Pixel

什么是Point?苹果给的定义是用户空间的一个单位。在普通屏上,Point和Pixel是一比一的关系,而在高分屏上,它们的关系是一比四。这点和iOS是一样的。

对开发者来说,大部分情况下,我们根本不需要去考虑Pixel,因为我们程序中用到的坐标基本上都是以Point为单位的。在编写代码时,我们可以这样假设:世界上根本就不存在高分屏的Mac,新的MacBook Pro其实还是原来的1440*900。这样,我们就会都是以Point的方式去考虑坐标,从而保持程序高分屏和普通屏表现的一致性。这也是苹果推荐的方式。

那我们什么时候才需要考虑到Pixel呢?当我们准备操纵像素的时候。主要有以下几个地方:

  • Core Graphics。也就是说,当我们用到CG开头的API时,我们需要注意,它们的坐标大部分是以Pixel为单位的。

  • OpenGL。既然是绘制,自然要精确到像素级。

DPI和PPI

DPI:Dots Per Inch,每英寸点数,一般用来表示打印机或显示设备的精度。而在图像中,则一般使用PPI。

PPI:Pixels Per Inch,每英寸像素数,一般用来表示图像的精细度。

高分屏的DPI是144,是普通屏的两倍。此外,用系统截图工具截取的图片,其PPI也是144,同样是普通屏时的两倍。

支持高分屏,我们需要做些什么?

确认我们App运行在Framework-Scaled模式下

Cocoa App默认是以Framework-Scaled模式运行,不用做任何额外的事情。对于非Cocoa的App,如果要支持高分屏,需要做些修改了。

增加两倍图资源

和iOS一样,要支持高分屏,对所有图片,我们都需要在其旁边增加一个名字为“一倍图名字+@2x”的两倍图资源。对原来用图数量就比较多的程序来说,如QQ,设计师的工作量毫无疑问是巨大的。不仅如此,因为Mac窗体大小不像iOS那么统一,为了防止问题发生,切图时还要注意以下事项:

  • 两倍图的图片资源,其分辨率最好是一倍图严格的两倍;PPI和一倍图保持一样,还是72。如果不这样做,不仅在高分屏上有可能出现不符合我们预想的表现,普通屏也是会受影响的。这是因为这些错误有可能会导致系统判断两倍图关系失败,从而使普通屏下直接读取两倍图,导致界面展示异常。

  • 如果程序中还涉及到图片的叠加,那么这些用来叠加的图片,内容上最好也是严格的两倍。举个例子,如果一倍图中有根线的位置是第三行,那么两倍图中这根线的位置应该是第五行和第六行。否则,会出现在普通屏下对齐的图片在高分屏下却没有对齐的情况。

确认代码中的资源图片读取方法

要想让系统帮我们自适应使用一倍图和两倍图,我们最好尽量使用文档推荐的资源图片读取方法:NSImage的imageNamed:方法和NSBundle的imageForResource:方法,分别对应main bundle和其他bundle中图片的读取。如果之前代码中有使用其他资源图片读取方法的地方,最好替换掉。

确认资源图片读取时不要带后缀名

和iOS一样,如果我们想让系统自适应来使用一倍图和两倍图,读取时传入的图片名字就不能带有后缀名,否则读取的是那张指定名字的一倍图。xib中也是一样的情况。所以,请搜索全程序确认这点。

确认之前涉及图片size的代码是否有问题

NSImage的size是以Point为单位的,所以无论一倍图还是两倍图,其size都是一样的。而前面讲过CG层又是以Pixel为单位的,所以请详细检查转换时的代码。

检查有图片拉伸的地方是否有异常

首先注意一点, 拉伸图片时,系统会自动使用两倍图。这是因为,NSImage读取图片时其实是两幅图同时读入的,使用时再根据目标区域的大小决定使用哪张图。如果目标区域的大小是介于一倍图和两倍图之间,那么系统会使用两倍图,然后将其缩到目标区域大小。所以要注意喽,如果之前程序中有目标区域比图片大,那么赶紧确认下是否还表现正常,因为这里会使用两倍图的。

当然,如果需要,我们可以不让系统不这么做。通过NSImage的类方法setMatchesOnlyOnBestFittingAxis: 设定后,一倍图和两倍图就严格根据普通屏和高分屏来使用了。不过需要注意,该方法是10.7.4才有的。

一般来说,最好使用NSDrawThreePartImage和NSDrawNinePartImage来拉伸图像。

增加Point与Pixel的转换代码

之前因为普通屏下Point与Pixel是一比一的关系,所以有些代码无意中会将这两种坐标弄混。所以,最好确认下这方面的代码,特别是和屏幕相关的地方。

需要Point与Pixel之间的坐标转换时,使用Backing Coordinate System。NSView、NSWindow和NSScreen都有与其坐标转换的方法,尽量不要直接使用Scale Factor进行计算。

增加分辨率变化时的响应代码

前面提过,与iOS相比,Mac是支持多显示器和随时切换分辨率。当一个窗体在两个不同显示模式的显示器里来回拖拽时,这个窗体的显示模式和分辨率同时也在发生着变化。不过别担心,一旦这些发生变化,系统会自动帮我们重绘窗体,一倍图和两倍图之类的也会自动帮我们切换。不过,我们最好还是确认下,在发生这些变化的情况下,我们的表现是否还是正常的。

如果需要在显示模式切换时做些处理时,我们可以监听NSWindowDidChangeBackingPropertiesNotification。如果是自定义NSView,可以重载viewDidChangeBackingProperties方法,在里面做处理。

注意高分屏时截取的图像其PPI是144

当我们通过系统截图工具或QQ在高分屏中进行截图时,就会发现截取后的图像,其PPI是144,是普通屏的两倍。这并不难理解,因为高分屏单位距离的像素数就是普通屏的两倍。所以程序中使用截图的地方,要注意这点。

替换API

1)BASE COORDINATE SYSTEM相关

之前我们会经常使用Base Coordinate System来表示在window中的坐标,而这个坐标系因为高分屏将被抛弃。所以,和这个坐标系相关的API,我们最好都要替换掉。

NSView:

convertPointToBase:替换成convertPoint:toView:(view为nil)

convertSizeToBase:替换成convertSize:toView:

convertRectToBase:替换成convertRect:toView:

convertPointFromBase: 替换成convertPoint:fromView:

convertSizeFromBase: 替换成convertSize:fromView:

convertRectFromBase: 替换成convertRect:fromView:

NSWindow:

convertBaseToScreen:替换成convertRectToScreen:

convertScreenToBase:替换成convertRectFromScreen:

2)图片绘制相关

NSImage的两个方法compositeToPoint:和dissolveToPoint:因为涉及到Base Coordinate System,所以被建议替换成drawAtPoint:fromRect:operation:fraction:。

此外,lockFocus方法也建议用imageWithSize:flipped:drawingHandler:替换。前面提到过,NSImage其实是同时拥有一倍图和两倍图的,会根据目标区域来使用哪一张,而lockFocus其实只处理了一张。

还有,建议使用NSGraphicsContext来处理图像,因为它会自动帮我们处理Scale Factor。

3)SCALE FACTOR相关

因为高分屏Scale Factor的介入,旧Scale Factor相关的需要修改:

a)NSScreen和NSWindow的userSpaceScaleFactor;

b)HIGetScaleFactor方法需用HIWindowGetBackingScaleFactor替换;

c)NSWindow的NSUnscaledWindowMask常量将被抛弃;

一些Trick

如何往NSTEXTVIEW中添加高清GIF图

为了支持高清表情,我们更改了在NSTextView中添加gif图的实现方法,采用了NSFileWrapper的方式,通过NSFileWrapper的setIcon:方法将NSImage设进去。但修改后运行我们发现表情都不会动了。怎么回事?我们跟踪了好一会,途中尝试了几种不同的方法,终于在做了以下处理后使表情运行正常:

  1. 将表情资源文件的.gif后缀改成.png;

  2. 高分屏和普通屏分开读取图片,普通屏只读取一倍图,高分屏则采用不使用后缀名的方式读取。

这种做法确实很让人费解,但这确实是我们经过多次尝试后找到的解决办法。之后我们还会继续研究这个问题,希望能找到更好的解决办法。

如何在制作DMG包时让其FINDER背景也支持RETINA

Apple没有在高分屏指南的文档中提到任何与dmg相关的内容,也没有为之增加任何新的方法来做这件事。但在其文档中有提到,使用tiffutil来制作复合型的tiff格式图片。在此格式的图片中,同时存储着普通与高清版本图像。事实上经过我们的测试,这种tiff格式图片是可以被用作dmg背景的。具体命令是:

tiffutil -cathidpicheck 普通图 高清图 -out 目标图片名称

需要注意的是:

  • DropDMG暂时不支持将tiff作为背景,可以通过修改后缀名为png的方式绕过此限制。

  • 用这种方法生成的dmg,在查看时会在左侧有一道奇怪的白边。可能是Apple的实现问题。

工具推荐

高分屏模拟工具

新的MacBook Pro刚出来,货源紧缺,实在不好买到。别担心,Xcode的Graphics Tools可以让我们模拟高分屏。Graphics Tools可以到developer.apple.com下载。 如何模拟高分屏:

  1. 将Graphics Tools中的Quartz Debug打开;

  2. 选择UI Resolution菜单;

  3. 在弹出来的窗口中选择“Enable HiDPI display modes”;

  4. 注销并重新登录;

  5. 在系统偏好设置的显示器面板中,选择后面带有HiDPI标志的分辨率。

这样,系统就会模拟高分屏的显示模式。略感不足的是,模拟后的分辨率只有原来的四分之一,操作各种不习惯。没办法,毕竟是一比四的关系啊。

两倍图检查工具

一下子换那么多图,哪些地方的两倍图显示正确,哪些地方还没换,我等肉眼凡胎,检查时难免纰漏。没关系,系统提供了自动标红的功能,帮助我们找出这些地方。

打开方式:在终端中,敲入以下命令

defaults write com.mycompany.myapp CGContextHighlight2xScaledImages YES

( com.mycompany.myapp就是我们需要检查的App名,如果是想检查所有的App,用-g替换 )

打开后,没有换成两倍图的地方,都会被红框标出来,非常方便。

UI实用工具

  • Layer Cake,直接从psd生成切图文件,甚至可以从普通psd直接生成高清版本的切图,在为旧软件增加高清支持时尤其方便。

  • IconKit,支持生成高清版本的icns文件。

  • PaintCode,矢量绘图并直接生成Objective-C代码,自然支持高清,大大减少UI和开发的工作。

  • 来源:iBlog

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Retina_masks 是一个基于 RetinaNet 的目标检测算法,它主要采用了 Mask R-CNN 的思想,将目标检测任务扩展到了实例分割任务。具体来说,Retina_masks 在 RetinaNet 的基础上添加了一个分割分支,用于预测每个检测到的目标的掩模。这样,Retina_masks 可以同时输出目标的类别、边界框和掩模信息,从而实现了目标检测和实例分割的结合。 相比于传统的目标检测算法,Retina_masks 具有以下优点: 1. 精度高:Retina_masks 不仅可以检测目标,还可以准确地分割出目标的轮廓,从而提高了检测的精度。 2. 速度快:Retina_masks 基于 RetinaNet 的架构,具有高效的特征提取和分类能力,因此速度比较快。 3. 适用范围广:Retina_masks 可以应用于各种不同的场景,包括自然图像、视频和医学图像等。 总之,Retina_masks 是一种非常优秀的目标检测和实例分割算法,具有很高的实用价值。 ### 回答2: retina_masks是一种图像处理技术,用于处理高分辨率图像中的细节和遮罩。它是通过使用多个图像金字塔和卷积运算来实现的。 retina_masks的作用是提取和突出显示图像中的细节并生成遮罩。首先,它将原始图像分解成多个尺度的图像金字塔,其中包含不同分辨率的图像。然后,对于每个尺度,使用卷积核对图像进行卷积操作,以便在图像的不同尺度上检测和突出显示细节。 使用retina_masks可以实现许多应用。例如,在医学图像处理中,可以使用retina_masks提取和突出显示医生关注的特定区域,以帮助诊断。在安防监控领域,retina_masks可以用于检测和跟踪人脸或其他关键特征。此外,retina_masks也可以用于图像增强,使得图像的细节更加清晰。 总之,retina_masks是一种利用多尺度图像金字塔和卷积运算的图像处理技术,用于提取和突出显示图像中的细节和生成遮罩。它在许多领域都有广泛应用,可以帮助实现图像增强、目标检测和区域提取等任务。 ### 回答3: retina_masks是指在计算机视觉中用于图像分割的一种技术。图像分割是指将图像中的不同对象或区域分离出来的过程。 retina_masks技术是基于人眼视网膜的工作原理而设计的。人眼的视网膜是由许多感光细胞组成的,这些细胞能够对不同位置和颜色的光信号做出反应。retina_masks技术模仿了这种机制,通过创建一个包含多个层次的模型来分析图像的不同特征。 retina_masks技术可以实现精确的图像分割,能够准确地识别并分离出图像中的各个对象或区域。它通过对图像进行多次处理,每次处理都利用前一次处理的结果来进一步优化分割效果。这种逐步迭代的处理过程使得分割结果更加准确、细致。 与传统的图像分割方法相比,retina_masks技术具有以下优势: 1. 高精度:retina_masks技术能够以像素级别的精度进行分割,能够准确地识别和分离图像中的各个对象或区域。 2. 多层次处理:retina_masks技术通过多次处理图像,每次处理都基于前一次处理的结果,能够逐步优化分割效果。 3. 自适应性:retina_masks技术能够根据图像的特点自动地调整参数,适应不同的图像和分割任务。 总之,retina_masks是一种基于人眼视网膜工作原理的图像分割技术,具有高精度、多层次处理和自适应性等优势。它在计算机视觉领域具有广泛的应用前景,可以用于目标识别、图像分析等领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值