SCALE FACTOR

In the corona simulator for windows I have my suffix set at

imageSuffix = {          ["@2x"] = 1.3,       },

but when the scale factor is “0.75895994378074”  it will use the @2x-suffixed images. Shouldn’t it only use the @2x-suffixed images if the scale factor is “1.3” or greater? That’s the simulate Galaxy S5.

On the simulated galaxy S3 it doesn’t use the @2x-suffixed images but  the scale factor is “0.50597329585383”

What’s the threshold? Shouldn’t it be “1.3”??

Just trying to get a grasp on when the @2x-suffixed images are used. Am I missing something?

This all started when my Galaxy Tab GT-P5210 wasn’t using the  dynamic image selection. It has a screen 1280 x 800 and Aspect Ratio 16:10.    But on my Apple iPad it was working.

Any help is greatly appreciated.

Can you post your config.lua?

You’re assertion is correct.  If the scale factor is 1.3 or less you should get the 1x images.

Rob

@Rob, Here’s the config file. You mentioned in your article that

“devices with a the screen width greater than 1040 pixels will use the larger “@2x””

So I think I understand why the scale factor gets overridden in the simulator devices –

I think even though the Scale Factor is less then 1.3 (in the simulator devices)if the width is greater then 1040 its going to trigger Larger “@2x

My Samsung Tab has a 800 pixel width and a scale factor of 0.6, so even though its a 10 Inch Tablet the width or the scale factor  won’t trigger the @2x-suffixed images.

--calculate the aspect ratio of the device local aspectRatio = display.pixelHeight / display.pixelWidth application = { &nbsp;&nbsp; content = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; antialias = false, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width = aspectRatio \> 1.5 and 800 or math.ceil( 1200 / aspectRatio ), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height = aspectRatio \< 1.5 and 1200 or math.ceil( 800 \* aspectRatio ), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scale = "letterBox", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fps = 60, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --audioPlayFrequency = 22050, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; imageSuffix = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ["@2x"] = 1.3, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, &nbsp;&nbsp; }, &nbsp;&nbsp; license = { &nbsp;&nbsp;&nbsp; google = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key = "GOOGLE KEY", &nbsp;&nbsp;&nbsp; }, &nbsp; }, }

800 * 1.3 = 1040.

Your 800 x 1200 is defining a virtual screen.  On a smaller device like say an iPhone 4, your content area is bigger than the device (640x960) so we have to scale everything down by (640 / 800).  If your device is a 1080p device then 1080 / 800 is 1.35 so it gets the @2x images.  We have to scale everything up by 1.35.  The S3 is a 720 x 1280 device.   720 / 800 so the scale factor for this use is 0.9 since the 720 is less than the 800.   Now if your device is in landscape mode, it actually uses the height for the calculations so 1280 / 1200 is 1.066 which should still use the 1x images.

I took your config.lua and with this main.lua:
 

local p = display.newImageRect("testimage.png", 100, 100) p.x = display.contentCenterX p.y = display.contentCenterY print(display.contentWidth) print(display.contentHeight) print(display.actualContentWidth) print(display.actualContentHeight) print(display.pixelWidth) print(display.pixelHeight)

I also created a testimage.png file at 100x100 and drew a blue #1 on it.  Then I created a 200x200 and drew a red #2.   On the simulator when using the S3 skin, I get the #1 as expected.  When I use the S5 skin, I get the #2 as expected.  The values I’m printing out are what I expect.

Just as an fyi, in another thread, a user suggested that we should use math.floor() instead of math.ceil() in the calculations.  After running both ways I concur, but it’s not the cause of your issue.

How do you know its using the @2x images?  Are you using display.newImage() or display.newImageRect() (though that’s a rhetorical question since display.newImage() uses the exact file and doesn’t use our dynamic image size.)

Rob

a

I marked the @2x images with a big yellow “2” text. :slight_smile:

Yeah, I use the display.newImageRect. The dynamic image selection works sometimes but with the wrong scale factor number. Seemingly. Unless I’m doing something wrong.

But if you’re saying that the scale factor is calculated  differently  “Landscape” mode then in “Portrait” mode the docs don’t spell that out very well:

The docs say to use the code below in the main to get the scale factor: but it doesn’t say “Portrait” mode only

print( display.pixelWidth / display.actualContentWidth )

https://docs.coronalabs.com/daily/guide/basics/configSettings/index.html

 Is the scale factor calculated like this for “Landscape” mode?

print( display.pixelHeight / display.actualContentHeight )

Thanks for your help  Rob

I made a blank project using my config file and one background image(the @2x image is marked) in “landscapeRight” orientation.

-- -- main.lua -- ----------------------------------------------------------------------------------------- -- Your code here \_G.left&nbsp;&nbsp;&nbsp; = 0 + display.screenOriginX \_G.top&nbsp;&nbsp;&nbsp;&nbsp; = 0 + display.screenOriginY \_G.right&nbsp;&nbsp; = display.contentWidth&nbsp; - display.screenOriginX \_G.bottom&nbsp; = display.contentHeight - display.screenOriginY \_G.deviceW = display.actualContentWidth&nbsp; - display.screenOriginX\*2 \_G.deviceH = display.actualContentHeight - display.screenOriginY\*2 \_G.centerX = display.contentWidth /2 \_G.centerY = display.contentHeight/2 \_G.screenW = deviceW \_G.screenH = deviceH local Tmp&nbsp; = display.newImageRect( "bg\_castle1.jpg", 1425, 900) Tmp.anchorX = 0 Tmp.anchorY = 0 Tmp.xScale = deviceW / Tmp.width Tmp.yScale = deviceH / Tmp.height Tmp.x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0 Tmp.y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0 print( display.pixelWidth&nbsp; ) print( display.pixelHeight&nbsp; ) print(display.contentWidth) print(display.contentHeight) print(display.actualContentWidth) print(display.actualContentHeight) print( display.imageSuffix ) print( display.pixelWidth / display.actualContentWidth ) print( display.pixelHeight / display.actualContentHeight )

The simulator Galaxy S3 output

720    
1280    
1423    
800    
1423    
800.4375    
nil    
0.50597329585383    
1.5991254782541    
 

Then this is Galaxy S5

1080    
1920    
1423    
800    
1423    
800.4375    
@2x    
0.75895994378074    
2.3986882173811  

I get the same results (the Galaxy S3 1x image, the Galaxy S5 2x image) BUT which is the scale factor??(This is what’s confusing me)

Based on the suffix ["@2x"] = 1.3

If its = display.pixelHeight / display.actualContentHeight

The Galaxy S3 = 1.5991254782541

The Galaxy S5 =2.3986882173811 

Then they both should use the 2x image??

If its = display.pixelWidth / display.actualContentWidth

The Galaxy S3 = 0.50597329585383

The Galaxy S5 = 0.75895994378074

Then they both should use the 1x image ??

The scale factor doesn’t make sense (at least the way I’m calculating it)

I think I know where your issues are originating.  pixelheight and pixelWidth don’t change when the orientation changes.  In other words it’s the actual pixelWidth and pixelHeight of the device.  Remember Corona SDK’s config.lua is always treated as a portrait app.

You need to forget that display.actualContentXXX and display.contentXXX exist when calculating the scale factor for our dynamic images.  Lets forget your config.lua for a second and consider this simple one:

application = { &nbsp;&nbsp; content = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width = 800, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height = 1200, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scale = "letterbox", -- note should be all lower case! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fps = 60, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; imageSuffix = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ["@2x"] = 1.3, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, &nbsp;&nbsp; }, }

Your app’s output for display.contentWidth will be 800.  That’s what you set it too.  Same for display.contentHeight, it will be 1200.  Now for the S3 skin because it’s more of a HDTV shape screen (16:9) vs. the 3:2 screen you defined at 800 x 1200 (a 4x6 photo shape), the actualContentWidth will be 800, but the longer screen means the display.actualContentHeight will be 1423.

The Moderinzing config.lua attempts to make sure that display.contentHeight matches display.actualContentHeight.  That’s what all that math is doing.  display.contentHeight and display.actualContentHeight should return the same values (plus a few fractions of a point).    Since these four values are needed in your program to be based around orientation of your app, so we flip the values to match the orientation.  In other words, you can’t use them to calculate the scaling factor of the device.

So how does this impact picking @2x images.  Well if you keep in mind that config.lua is always treated in portrait orientation.   So the scale factor we use is

display.pixelWidth / Your defined width, or for the S3:  720 / 800 or 0.9.   The S5 is 1080 / 800 or 1.35.   And for all intents and purposes this is:  display.pixelWidth / display.actualContentWidth, but once you get into main.lua, we’ve flipped the two contentWidth and contentHeight values and you can’t in your app calculate the scale factor unless you take orientation in to factor.

Rob

Thanks Rob, I was so fixated on calculating the actual scale factor. Too bad display.* doesn’t have property like “display.imageScaleFactor” or something.

Also thanks for pointing out that “letterbox” wasn’t all lowercase. :slight_smile:

What about this:  https://docs.coronalabs.com/api/library/display/contentScaleX.html and https://docs.coronalabs.com/api/library/display/contentScaleY.html

Rob

Can you post your config.lua?

You’re assertion is correct.  If the scale factor is 1.3 or less you should get the 1x images.

Rob

@Rob, Here’s the config file. You mentioned in your article that

“devices with a the screen width greater than 1040 pixels will use the larger “@2x””

So I think I understand why the scale factor gets overridden in the simulator devices –

I think even though the Scale Factor is less then 1.3 (in the simulator devices)if the width is greater then 1040 its going to trigger Larger “@2x

My Samsung Tab has a 800 pixel width and a scale factor of 0.6, so even though its a 10 Inch Tablet the width or the scale factor  won’t trigger the @2x-suffixed images.

--calculate the aspect ratio of the device local aspectRatio = display.pixelHeight / display.pixelWidth application = { &nbsp;&nbsp; content = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; antialias = false, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width = aspectRatio \> 1.5 and 800 or math.ceil( 1200 / aspectRatio ), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height = aspectRatio \< 1.5 and 1200 or math.ceil( 800 \* aspectRatio ), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scale = "letterBox", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fps = 60, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --audioPlayFrequency = 22050, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; imageSuffix = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ["@2x"] = 1.3, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, &nbsp;&nbsp; }, &nbsp;&nbsp; license = { &nbsp;&nbsp;&nbsp; google = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key = "GOOGLE KEY", &nbsp;&nbsp;&nbsp; }, &nbsp; }, }

800 * 1.3 = 1040.

Your 800 x 1200 is defining a virtual screen.  On a smaller device like say an iPhone 4, your content area is bigger than the device (640x960) so we have to scale everything down by (640 / 800).  If your device is a 1080p device then 1080 / 800 is 1.35 so it gets the @2x images.  We have to scale everything up by 1.35.  The S3 is a 720 x 1280 device.   720 / 800 so the scale factor for this use is 0.9 since the 720 is less than the 800.   Now if your device is in landscape mode, it actually uses the height for the calculations so 1280 / 1200 is 1.066 which should still use the 1x images.

I took your config.lua and with this main.lua:
 

local p = display.newImageRect("testimage.png", 100, 100) p.x = display.contentCenterX p.y = display.contentCenterY print(display.contentWidth) print(display.contentHeight) print(display.actualContentWidth) print(display.actualContentHeight) print(display.pixelWidth) print(display.pixelHeight)

I also created a testimage.png file at 100x100 and drew a blue #1 on it.  Then I created a 200x200 and drew a red #2.   On the simulator when using the S3 skin, I get the #1 as expected.  When I use the S5 skin, I get the #2 as expected.  The values I’m printing out are what I expect.

Just as an fyi, in another thread, a user suggested that we should use math.floor() instead of math.ceil() in the calculations.  After running both ways I concur, but it’s not the cause of your issue.

How do you know its using the @2x images?  Are you using display.newImage() or display.newImageRect() (though that’s a rhetorical question since display.newImage() uses the exact file and doesn’t use our dynamic image size.)

Rob

a

I marked the @2x images with a big yellow “2” text. :slight_smile:

Yeah, I use the display.newImageRect. The dynamic image selection works sometimes but with the wrong scale factor number. Seemingly. Unless I’m doing something wrong.

But if you’re saying that the scale factor is calculated  differently  “Landscape” mode then in “Portrait” mode the docs don’t spell that out very well:

The docs say to use the code below in the main to get the scale factor: but it doesn’t say “Portrait” mode only

print( display.pixelWidth / display.actualContentWidth )

https://docs.coronalabs.com/daily/guide/basics/configSettings/index.html

 Is the scale factor calculated like this for “Landscape” mode?

print( display.pixelHeight / display.actualContentHeight )

Thanks for your help  Rob

I made a blank project using my config file and one background image(the @2x image is marked) in “landscapeRight” orientation.

-- -- main.lua -- ----------------------------------------------------------------------------------------- -- Your code here \_G.left&nbsp;&nbsp;&nbsp; = 0 + display.screenOriginX \_G.top&nbsp;&nbsp;&nbsp;&nbsp; = 0 + display.screenOriginY \_G.right&nbsp;&nbsp; = display.contentWidth&nbsp; - display.screenOriginX \_G.bottom&nbsp; = display.contentHeight - display.screenOriginY \_G.deviceW = display.actualContentWidth&nbsp; - display.screenOriginX\*2 \_G.deviceH = display.actualContentHeight - display.screenOriginY\*2 \_G.centerX = display.contentWidth /2 \_G.centerY = display.contentHeight/2 \_G.screenW = deviceW \_G.screenH = deviceH local Tmp&nbsp; = display.newImageRect( "bg\_castle1.jpg", 1425, 900) Tmp.anchorX = 0 Tmp.anchorY = 0 Tmp.xScale = deviceW / Tmp.width Tmp.yScale = deviceH / Tmp.height Tmp.x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0 Tmp.y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0 print( display.pixelWidth&nbsp; ) print( display.pixelHeight&nbsp; ) print(display.contentWidth) print(display.contentHeight) print(display.actualContentWidth) print(display.actualContentHeight) print( display.imageSuffix ) print( display.pixelWidth / display.actualContentWidth ) print( display.pixelHeight / display.actualContentHeight )

The simulator Galaxy S3 output

720    
1280    
1423    
800    
1423    
800.4375    
nil    
0.50597329585383    
1.5991254782541    
 

Then this is Galaxy S5

1080    
1920    
1423    
800    
1423    
800.4375    
@2x    
0.75895994378074    
2.3986882173811  

I get the same results (the Galaxy S3 1x image, the Galaxy S5 2x image) BUT which is the scale factor??(This is what’s confusing me)

Based on the suffix ["@2x"] = 1.3

If its = display.pixelHeight / display.actualContentHeight

The Galaxy S3 = 1.5991254782541

The Galaxy S5 =2.3986882173811 

Then they both should use the 2x image??

If its = display.pixelWidth / display.actualContentWidth

The Galaxy S3 = 0.50597329585383

The Galaxy S5 = 0.75895994378074

Then they both should use the 1x image ??

The scale factor doesn’t make sense (at least the way I’m calculating it)

I think I know where your issues are originating.  pixelheight and pixelWidth don’t change when the orientation changes.  In other words it’s the actual pixelWidth and pixelHeight of the device.  Remember Corona SDK’s config.lua is always treated as a portrait app.

You need to forget that display.actualContentXXX and display.contentXXX exist when calculating the scale factor for our dynamic images.  Lets forget your config.lua for a second and consider this simple one:

application = { &nbsp;&nbsp; content = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width = 800, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height = 1200, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scale = "letterbox", -- note should be all lower case! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fps = 60, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; imageSuffix = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ["@2x"] = 1.3, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, &nbsp;&nbsp; }, }

Your app’s output for display.contentWidth will be 800.  That’s what you set it too.  Same for display.contentHeight, it will be 1200.  Now for the S3 skin because it’s more of a HDTV shape screen (16:9) vs. the 3:2 screen you defined at 800 x 1200 (a 4x6 photo shape), the actualContentWidth will be 800, but the longer screen means the display.actualContentHeight will be 1423.

The Moderinzing config.lua attempts to make sure that display.contentHeight matches display.actualContentHeight.  That’s what all that math is doing.  display.contentHeight and display.actualContentHeight should return the same values (plus a few fractions of a point).    Since these four values are needed in your program to be based around orientation of your app, so we flip the values to match the orientation.  In other words, you can’t use them to calculate the scaling factor of the device.

So how does this impact picking @2x images.  Well if you keep in mind that config.lua is always treated in portrait orientation.   So the scale factor we use is

display.pixelWidth / Your defined width, or for the S3:  720 / 800 or 0.9.   The S5 is 1080 / 800 or 1.35.   And for all intents and purposes this is:  display.pixelWidth / display.actualContentWidth, but once you get into main.lua, we’ve flipped the two contentWidth and contentHeight values and you can’t in your app calculate the scale factor unless you take orientation in to factor.

Rob

Thanks Rob, I was so fixated on calculating the actual scale factor. Too bad display.* doesn’t have property like “display.imageScaleFactor” or something.

Also thanks for pointing out that “letterbox” wasn’t all lowercase. :slight_smile:

What about this:  https://docs.coronalabs.com/api/library/display/contentScaleX.html and https://docs.coronalabs.com/api/library/display/contentScaleY.html

Rob