help with retina, saveImage etc...

I need some help.
I have made a funny little app based on a screenshot.
When i selected the screenshot in my photos the ‘retina’ switch was ON.
Everything works fine.
Then i have put my screenshot on my dropBox (manually, not with codea dropbax link) to share it with others.
Then i wrote the code to download this image, and save it with saveImage().
Now it doesnt work any more: the image is 2x bigger.
I read some things in the documentation of saveImage about @x2 but i dont understand what it says, and i don see 2 images in my documents folder, only one.
I am lost: how can i have it simple and one-to-one when i get the screenshot directly or when i get it from the web?
Has anyone encountered these problems and resolved them?
Thanks for your help.

@Jmv38 Not sure if this helps or not. I saved an image in my Dropbox folder from my Camera roll. I looked in my Dropbox folder and saw the one image I saved. I did a sync to the Dropbox app and it said it was syncing 2 items. I looked in the Dropbox app folder and there were 2 images there with the name I use. One was listed as @2x and about 3 times the size of the other one. So, both images are probable there, you just need to get the smaller one.

Thanks. Actually i think what want is: i have an image of retina resolution in link, how can i use it inside the ipad with the correct width and height? I do not want to use dropbox sync. Maybe i should sprite it into a widthxheight image using setContext? There seems to be a hidden parameter, in addition of width and height, for defining an image. What is it?

@Jmv38 - Codea shows the same WIDTH and HEIGHT for iPads 1 to 3, even though iPad 3 has twice the number of pixels each way, ie 4x bigger.

This means that it needs the 2x image for iPad 3, and the normal size image for iPad 1 and 2, so the screen can look the same for all ipads. Codea will automatically use the right image for each type of iPad. So the 2x image is the correct “one to one” image for iPad 3, and the 1x image is “one to one” for earlier iPads.

The introduction of even higher density iPhones has led to Simeon talking about using 3x images as well…

Here is the way it works:

saveImage: This looks at the scale factor of the device you are using. If your device has a scale factor of “2”, then it will save an @2x version of the image at full resolution, then a regular version of the image at half resolution.

readImage (sprite, etc): Codea will look for an @2x version of the file if you are on a retina device. If not, it will load the regular version, but this may look blurry. What happened in your situation was you imported a file as retina, moved it to dropbox, and re-imported it by just downloading it. Codea no longer knew that it was supposed to be treated as a “retina” file and so it appeared to be twice as large (but probably blurry).

Retina switch during import: This is to tell Codea whether you are importing an image you would like to be treated as retina. If the switch is off, Codea will import only the regular file at its original resolution. This means the image will look “blurry” on a retina iPad. If the switch is on, Codea will treat the image you are importing as the “@2x” version, meaning that the image will render at half the size its actual resolution dictates, but will look crisp on retina iPad. Codea will also save out a regular version of the image for non-retina use.

@3x adds some complexity to all this, but it’s a necessary evil when dealing with different screen densities.

@Simeon - thanks for the explanation

But where do I find “Retina switch during import”?

When you import photos via the sprite picker (i.e., from your photo library). There is a switch to toggle “retina”. When you activate it you should notice that the reported dimensions of the image are halved (this simply means that 2x2 pixels in the image will be used to represent 1x1 logical point on your retina sized device).

@Simeon thanks for the explanation. You correctly described ny problem, but you did not tell me how to fix it (or i missed it). How do i get it to work correctly with http.request and saveImage? The ‘retina switch’ only exists during import from sprite picker, not in my process.
So what should i do to share this game on the forum with crisp images???
ps: my loading code:

Screen = class()

function Screen:save(img,name)
    print("saving "
    saveImage(name, img)
function Screen:load(url,name)
    print("requesting "
    http.request(url,function(data) self:save(data,name) end)

function Screen:loadImages()
    print("Images must be loaded first")
    add0 = ""
    name0 = "Documents:splashScreenEmpty"
    add1 = ""
    name1 = "Documents:splashScreenFull"
    add3 = ""
    name3 = "Documents:pirate"

@Jmv38 good point. I think there’s three possible solutions we could implement:

  1. If http.request grabs an image from a URL ending in @2x.extension then the image is loaded as a retina image with a scale factor of 2 (same goes for @3x)
  2. We expose image.scale as a property and allow you to override the scale factor for a particular image, which would then be used by saveImage
  3. We add an argument to saveImage that allows you to override the scale factor (e.g., saveImage(name, img, scale))
  4. We do all three of the above

I favor 2/ and 3/.
1/ is the kind of semi-automatic, semi-transparent trick that i dont like. I prefer explicit commands as 2/ and 3/. Actually 2/ would be enough to cover everything?

@Jmv38 Item 2 is implemented for the next build

Great! Actually, i was think of a solution 4/, which is maybe what we really need:
4/ saveImage( name, img, sourceScale ).
sourceScale is the original scale used for img. The preson who created the image knows his scale so he can write that into the program. However users will have different scales so the creator has to manage each case himself. With 4/ codea would automatically rescale the image with userScale / sourceScale. On the other hand, i could write this formula in my program too with 2/. If i can read userScale.

@Jmv38 I’m not sure I understand correctly, the scale of the image should not really be tied to the display scale in any way.

sourceScale should be the same as image.scale.

For example, if I know my image at is a 2x retina image, then I can assign a scale of 2 to the image after it downloads. Codea will then render the image as if 2x2 of its pixels = 1x1 logical point. If I assign 3, then a 3x3 block of pixels becomes 1x1 logical point.

When you use saveImage on an image with a scale of 3, Codea will actually write three separate files out: picture.png, picture@2x.png and picture@3x.png. Depending on what device a person has, theirs will choose the most appropriate image to load.

(saveImage has further behaviour quirks to handle weird edge cases. For example it needs to know to delete any @2x or @3x images with the same name if you are saving an @1x image, because they might be leftover from a save of an image with the same name from a previous save operation on a different scale factor)

I didnt belive that codea actually wrote several images in documents because i see only one. How come i dont see multiple copies on my device?

@Jmv38 They’re hidden to stop confusion.

@SkyTheCoder Then i understand better what Simeon says. Well, i guess best thing will be to try it and see what happens.

@Jmv38 as @SkyTheCoder says, the sprite picker only shows the base image - because all scales are really just representations of the one image. If you look on the file system (or even in Dropbox on your computer) you should see the variants.

ok. Thanks.