Adobe AIR在iPhone4s和iPad mini上的Stage.contentsScaleFactor始终为1。

3

我的应用程序只是一个来自FlashDevelop的AIR Mobile AS3项目模板,包括application.xml文件和Main类。

在Main类中,我使用stage.contentsScaleFactor值创建了一个文本字段,并在第一个Event.RESIZE之后显示文本。

var textField:TextField = new TextField();
textField.appendText("Size: " + stage.stageWidth + " x " + stage.stageHeight + "\n");
textField.appendText("Scale: " + stage.contentsScaleFactor + "\n");
addChild(textField);

我的iPhone支持视网膜屏幕,我得到了:

尺寸: 960 x 640

比例: 1

用于:

<requestedDisplayResolution>high</requestedDisplayResolution>

并且

尺寸:480 x 320

缩放比例:1

适用于

<requestedDisplayResolution>standard</requestedDisplayResolution>.

iPad的情况几乎相同,

尺寸:2048 x 1536

缩放比例:1

对于高清,以及

尺寸:1024 x 768

缩放比例:1

对于标准

我正在使用最新的AIR SDK 18.0.0.142(beta)进行编译,-swf-version=29。发布版AIR SDK 18的结果相同。

对于AIR 14 SDK和-swf-version=25,我得到一些垃圾值作为大小(看起来像我的swf宽度和高度乘以contentsScaleFactor),但contentsScaleFactor仍为1

编辑: 我遇到了各种问题,这些问题在网络上提到了contentsScaleFactor(例如这个)。他们声称,在Retina显示屏上,contentsScaleFactor应该是2。 这就是这个属性的文档:

指定舞台的有效像素缩放因子。在标准屏幕上,此值通常为1,在HiDPI(即Retina)屏幕上,此值为2。当在HiDPI屏幕上渲染舞台时,像素分辨率加倍;即使将舞台缩放模式设置为StageScaleMode.NO_SCALE。 Stage.stageWidth和Stage.stageHeight仍然以经典像素单位报告。注意:此值可以根据舞台是否在HiDPI或标准屏幕上而动态更改。

此外,使用

<requestedDisplayResolution>standard</requestedDisplayResolution>

即使我使用wantsBestResolution设置为trueconfigureBackBuffer,在iPad上仍然得到1024*768的缓冲区。我通过在128*128四边形上绘制锐利的256*256纹理进行验证-结果模糊。然后我用相同的方式做了同样的事情。
<requestedDisplayResolution>high</requestedDisplayResolution>

我得到了相同物理尺寸的清晰图像。
我的实际问题是:
- 在Retina iPad/iPhone上,`contentsScaleFactor`是否应该为2?如果是这样,我是否遗漏了一些编译器/打包器选项? - 我如何确定对于`requestedDisplayResolution=standard`,我的舞台是否被缩放? - 如果在移动设备上`contentsScaleFactor`不起作用,那么这个属性有什么用途?例如,在具有Retina显示屏的Mac上,它是否有效?
编辑2:
在具有Retina显示屏的Mac上,`contentsScaleFactor`可以正常工作,并报告为`2`。

你无法从设备中获取DPI。你可以计算出DPI,但设备不会直接提供它给我们(由于某些奇怪的原因)。你的应用程序不应该进行缩放,因为缩放会消耗CPU资源。你应该在代码中自己实现缩放。 - moot
3个回答

0

从评论中:

是的,这就是我现在为iOS设备所做的,但不幸的是, Capability.screenDPI总体上是不可靠的。在桌面上它总是72, 在安卓上是一些“随机”的值,并且不考虑当前监视器的DPI

也许你需要的不是那么多每英寸点数,而是你正在寻找每英寸像素数DPI适用于将墨水点打印在纸上。 PPI表示实际英寸对应的像素数。别担心,即使维基百科文章承认“...已经成为惯例将PPI称为DPI,尽管PPI指的是输入分辨率(现在我们明白了DPI是打印分辨率

这意味着您应该忘记Capability.screenDPI,而是开始在计算中包括Capabilities.screenResolutionX(显示宽度)和Capabilities.screenResolutionY(显示高度)数字。
以下是一些反馈的代码。希望对您有所帮助:
PS:通过使用尺子对准计算机屏幕来双重检查Flash跟踪。
var scrn_W : uint = Capabilities.screenResolutionX;
var scrn_H : uint = Capabilities.screenResolutionY;
var scrn_DPI : uint = Capabilities.screenDPI;

var init_stageW : int = stage.stageWidth; var init_stageH : int = stage.stageHeight;

//Diagonal in Pixels
var scrn_Dg_Pix : Number = int( Math.sqrt( scrn_W * scrn_W + scrn_H * scrn_H ) );

//Diagonal in Inches
var scrn_Diag : Number = int( Math.sqrt( scrn_W * scrn_W + scrn_H * scrn_H ) ) / 100;

var scrn_PPI : uint = int( Math.sqrt( scrn_W * scrn_W + scrn_H * scrn_H ) ) / scrn_Diag;
//or scrn_PPI = scrn_Dg_Pix / scrn_Diag; //gives same result as above line of code

var dot_Pitch : Number = scrn_W / ( Math.sqrt( scrn_W * scrn_W + scrn_H * scrn_H ) ) / (scrn_Diag * 25.4) / scrn_W;

var scrn_Inch_W : Number = ( scrn_W / scrn_PPI ); var scrn_Inch_H : Number = ( scrn_H / scrn_PPI );

var result_Num : Number = 0; var temp_Pix_Num:Number = 0;
var testInch : Number = 0; var my_PixWidth : Number = 0; 

stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.RESIZE, resizeListener);  //just in case 


////////////////////
//// FUNCTIONS

function inch_toPixels( in_Num : Number) : Number
{
    temp_Pix_Num = in_Num;
    result_Num = scrn_PPI * temp_Pix_Num;
    return result_Num; 
}

function pixels_toInch( in_Num : Number) : Number
{
    temp_Pix_Num = in_Num;  
    result_Num =  temp_Pix_Num / scrn_PPI;
    return result_Num; 
}

function cm_toInch( in_CM : Number) : Number
{
    //inch = cm * 0.393700787; //from centimetre to inch
    result_Num = in_CM * 0.393700787; return result_Num; 
}

function inch_toCM( in_Inch : Number) : Number
{
    //cm = inch * 2.54; //from inch to centimetre
    result_Num = in_Inch * 2.54; return result_Num;
}


function resizeListener (e:Event):void 
{ 
    // Handle Stage resize here (ie. app window's Scale Drag / Minimize etc)
    //trace("new stageWidth: " + stage.stageWidth + " new stageHeight: " + stage.stageHeight);
}

///////////////
//// TRACES

trace("Stage Init Width  : " + init_stageW);
trace("Stage Init Height : " + init_stageH);

trace("Screen Width     : " + scrn_W);
trace("Screen Height    : " + scrn_H);
trace("Screen DPI       : " + scrn_DPI);
trace("Screen PPI       : " + scrn_PPI);

trace("Screen Diag      : " + scrn_Diag);
trace("Screen Diag Pix  : " + scrn_Dg_Pix);

trace("Dot Pitch        : " + dot_Pitch);
trace("Disp Width (inches)  : " + scrn_Inch_W );
trace("Disp Height (inches) : " + scrn_Inch_H );

谢谢,但我知道如何制作解决方案。我想知道我的应用程序是否在Retina显示屏上运行。顺便说一句,这个解决方案在Android上也不起作用:我有两个屏幕尺寸相同的Fly设备(差异小于厘米的分数),分别为320480和480800“Capabilities.resolution”,并且两者都具有“Capabilities.screenDPI = 240”。 - user2512323
我们使用DPI是因为这是有问题的属性 - screenDPI。screenDPI不起作用。PPI和DPI完全类似。如果不知道某个东西的物理尺寸 - 无论是像素还是显示器,都无法获得DPI、PPI或任何物理测量值。 - moot

0
使用Capability.screenDPI获取DPI比率,将stage.stageWidth除以screenDPI。在iPad上,您将获得约8个(一个DPI单位=约2个手指的房地产),DPI为您提供密度。现在比较两者,非视网膜iPad = 132像素/DPI的8个DPI单位,视网膜iPad = 264像素/DPI(高清)的8个DPI单位,等等...

是的,这就是我现在为iOS设备所做的,但不幸的是,Capability.screenDPI通常是不可靠的。在桌面上它总是72,在Android上有一些“随机”的值,并且没有考虑到舞台正在运行的当前监视器DPI(stage.contentsScaleFactor被记录为应该报告这些内容)。 - user2512323
值在Android上并不像你所说的那样随机,无论是从Flash还是本地获取,这些值对于高清设备始终是高清的,这才是最重要的。 - BotMaster
我有一部分辨率为480320,屏幕密度为240 dpi的安卓手机。另外还有一部800480的手机,它的物理屏幕大小几乎相同,也是240 dpi。此外,高清显示和高dpi是不同的概念 - 我需要确定给定屏幕分辨率(例如1000),应该渲染10个100px列表项还是5个200px的hidpi项目。 - user2512323
1
你需要对DPI值进行分类并分配类别。例如,在Flex中,320以上的任何值都被视为hdpi,而Flex仅处理3个类别。如果您愿意,可以处理更多类别,但不要将十几个或任何单个dpi值作为自己的类别处理。为了获得更准确的dpi值,您可以使用本机方式编写ANE,但在某些Android设备上(不是大多数设备,但会发生),DPI值仍将返回不正确。 - BotMaster

0

很遗憾,我不能在我的项目中使用Flex。 - user2512323

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接