How to make an image "lower quality" at run time?

My app downloads images when it’s running. Therefore an image shown on the screen is downloaded from the Internet, such as a news article image.

Usually I try to set xScale/yScale for the image. However, I found with scaling, the image is still too “high quality”. 

I mean if I show 10 images on the screen, the scrolling of the screen is kind of jammed. I think it’s because those 10 images are all too “high quality”.

Is there any function or any way in CoronaSDK I can use to make an image “lower quality” before I put it on the screen?

Do you mean you want it to be a higher quality image when “zoomed in”, and then show a lower quality image when “zoomed out”?

If so, the easiest way I can think is to actually download 2 of each image e.g. “myImage.png” and “myImage_LowRes.png”. Obviously you would need to create the low res image and upload that to your server.  

Then during runtime, just change the image fill so it uses the new image:

if myObject.xScale \< 0.5 then myObject.fill = {type = "myImage.png", filename = "texture1.png", baseDir = system.DocumentsDirectory} else myObject.fill = {type = "myImage\_LowRes.png", filename = "texture1.png", baseDir = system.DocumentsDirectory} end

@Alan

no, the image is downloaded via Internet. I don’t even know the image content or size because it is downloaded from the Internet when the app is run, and the image location is obtained by a database query, so it’s not fixed.

I understand that the image is downloaded from the internet, however as far as I know there is no way to change the resolution of the image itself in Corona SDK.  

If you need different to display an image at multiple resolutions at runtime then you need image files for those different resolutions. You don’t need to know the content or size - you just need to have the 2 images on the server, then download them both and use whichever one is currently needed.

That said, you shouldn’t be having problems if you are showing just 10 images unless they are huge.

The images are not on my server. They are “random”. I don’t have two versions or control over any of them.

That’s why I asked… if someone knows any possible way to do it.

For example, scale it and save it and reload it. 

Or maybe some graphic function can do… or maybe it has to be done by some algorithm by program, etc…

Ah ok, it wasn’t clear that they were not your images being hosted online.  

You could do as you’ve suggested - show the image, scale it, save it, reload it but you will need to “hide” this so the user doesn’t see it.

This is a bit crude, but should work:

local function downloadListener(event) if ( event.phase == "ended" ) then local hiresImage = display.newImage(event.response.filename, event.response.baseDirectory) hiresImage.xScale, hiresImage.yScale = 0.5, 0.5 local function saveImage() local fileNameWithoutExtension = event.response.filename:match("(%w+)%.") local extension = event.response.filename:match("^.+(%..+)$") print(fileNameWithoutExtension) print(extension) print(fileNameWithoutExtension.."\_lores"..extension) --this will save a half scale image which can be used when you need to show the lower res image display.save( hiresImage, fileNameWithoutExtension.."\_lores"..extension ) local function deleteOriginal() hiresImage:removeSelf() hiresImage = nil end timer.performWithDelay(100, deleteOriginal) end end end network.request(your\_params)

Thanks a lot for the code.

It is the last method I like to try though because it will take two extra i/o operations (save & reload). I have been experiencing some performance issue. (Many images to be downloaded and shown, and i/o operations impact UI smoothness a lot)

Do you mean you want it to be a higher quality image when “zoomed in”, and then show a lower quality image when “zoomed out”?

If so, the easiest way I can think is to actually download 2 of each image e.g. “myImage.png” and “myImage_LowRes.png”. Obviously you would need to create the low res image and upload that to your server.  

Then during runtime, just change the image fill so it uses the new image:

if myObject.xScale \< 0.5 then myObject.fill = {type = "myImage.png", filename = "texture1.png", baseDir = system.DocumentsDirectory} else myObject.fill = {type = "myImage\_LowRes.png", filename = "texture1.png", baseDir = system.DocumentsDirectory} end

@Alan

no, the image is downloaded via Internet. I don’t even know the image content or size because it is downloaded from the Internet when the app is run, and the image location is obtained by a database query, so it’s not fixed.

I understand that the image is downloaded from the internet, however as far as I know there is no way to change the resolution of the image itself in Corona SDK.  

If you need different to display an image at multiple resolutions at runtime then you need image files for those different resolutions. You don’t need to know the content or size - you just need to have the 2 images on the server, then download them both and use whichever one is currently needed.

That said, you shouldn’t be having problems if you are showing just 10 images unless they are huge.

The images are not on my server. They are “random”. I don’t have two versions or control over any of them.

That’s why I asked… if someone knows any possible way to do it.

For example, scale it and save it and reload it. 

Or maybe some graphic function can do… or maybe it has to be done by some algorithm by program, etc…

Ah ok, it wasn’t clear that they were not your images being hosted online.  

You could do as you’ve suggested - show the image, scale it, save it, reload it but you will need to “hide” this so the user doesn’t see it.

This is a bit crude, but should work:

local function downloadListener(event) if ( event.phase == "ended" ) then local hiresImage = display.newImage(event.response.filename, event.response.baseDirectory) hiresImage.xScale, hiresImage.yScale = 0.5, 0.5 local function saveImage() local fileNameWithoutExtension = event.response.filename:match("(%w+)%.") local extension = event.response.filename:match("^.+(%..+)$") print(fileNameWithoutExtension) print(extension) print(fileNameWithoutExtension.."\_lores"..extension) --this will save a half scale image which can be used when you need to show the lower res image display.save( hiresImage, fileNameWithoutExtension.."\_lores"..extension ) local function deleteOriginal() hiresImage:removeSelf() hiresImage = nil end timer.performWithDelay(100, deleteOriginal) end end end network.request(your\_params)

Thanks a lot for the code.

It is the last method I like to try though because it will take two extra i/o operations (save & reload). I have been experiencing some performance issue. (Many images to be downloaded and shown, and i/o operations impact UI smoothness a lot)