How can I display a image with size 10321x8817

How can I display a image with size 10321x8817?

The image is a complex route map that you can drag and drop with “touch”

You need to split it up into pieces and stitch them back together in a display group in Corona.

This example shows how I sliced up a 12000 x 8854 image into 30 slices then showed them in a draggable map.

It has the added feature of only ‘filling’ slices that are on-screen to save memory.

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2018/11/sliceNDice.zip

I used SSK for the dragger code and the FPS/Mem meters, but  the rest is pure Corona.

Yeah, it’s as Nick said. Loading an image of that size would require 2GB of texture memory and would be impossible to load as a single image. Your best bet would be to split it into pieces, as Nick also already stated. However, even still, if you were to split it into 1024x1024px images, you’d require approximately 9 x 11, i.e. 99 images. Each image would be 4MB, so you are again at ~396MB of texture memory used. This means that you’d have to implement a smart way of managing when and how you display those images in order to pull that off.

And just as I wrote my comment, Ed comes in with another fantastic demo of how it is done :smiley:

I’m very interested in knowing how the texture memory use in Ed’s example is only 13.51MB at its lowest, when loading a single 2000x1770 image should already require 2048 x 2048 x 4 / 1024 / 1024 = 16 MB of texture memory. Am I missing something here?

I’m just reporting what the system is telling me, but you’re right.  Something seems odd there.

Thank you very much for the answer! I thought about this way of displaying images, I’ll try your example. I am very pleased that this forum is a discussion and among the developers are not indifferent. I have one more question are there other examples of display images according to the technology roaminggamer.  Sorry for the late response, but we have different time zones.

Roaminggamer please tell me how to organize on Your example the restriction for the image goes beyond the visible part of the screen. For example: if the x coordinate is less -10321, the x coordinate is = -10321. I haven’t tried it yet, but as far as I understand map.does width contain the width of the entire map?

Hi.  I’m having trouble understanding your last couple of questions.

That said, you can find the API docs here:  https://docs.coronalabs.com/api/

Also, at the top of the page, are links to tutorials, guides, and other useful docs.

You’ll want to read more about display.*  properties and functions as a start.

roaminggamer, the question does sound strange in translation. figured it out, changed the code a little bit, I did it. Can I ask You another question, example how to realize zoom in and zoom out images.

local mapW = 21216 local mapH = 17219 local sliceW = 1768 local sliceH = 1721 local sliceA = 1722 -- sliceH + 1 local map = display.newGroup() map.anchorX = 0 map.anchorY = 0 map.x = common.centerX - mapW/2 map.y = common.centerY - mapH/2 -- -- Function to only fill image if it is on screen -- local function doOnScreenFillTest( self ) local x0 = self.x + self.parent.x + self.contentWidth local x1 = self.x + self.parent.x local y0 = self.y + self.parent.y + self.contentHeight local y1 = self.y + self.parent.y local onScreen = ( x0 \>= common.left and x1 \<= common.right ) and (y0 \>= common.top and y1 \<= common.bottom ) if( onScreen and self.lastFill == "fillT.png" ) then self.fill = { type = "image", filename = self.imgPath } self.lastFill = self.imgPath --print("SHOW", self.imgPath ) elseif( not onScreen and self.lastFill == self.imgPath ) then self.fill = { type = "image", filename = "fillT.png" } self.lastFill = "fillT.png" --print("HIDE", self.imgPath ) end end -- -- Create images from slices -- local slices = {} local curX = 0 local curY = 0 for row = 1, 10 do local slice for col = 1, 12 do local imgPath = "slices/geo/BigMap\_" .. col .. "-" .. row .. ".jpg" slice = display.newImageRect( map, imgPath, sliceW, sliceH ) slice.anchorX = 0 slice.anchorY = 0 slice.x = curX slice.y = curY curX = curX + sliceW slice.imgPath = imgPath slice.lastFill = slice.imgPath slice.doOnScreenFillTest = doOnScreenFillTest slices[slice] = slice slice:doOnScreenFillTest() end curX = 0 curY = curY + sliceH sliceH = sliceA end function map:touch ( event ) for key, val in pairs (slices) do val:doOnScreenFillTest() end if event.phase == "began" then self.markX = self.x self.markY = self.y elseif event.phase == "moved" then self.x = event.x - event.xStart + self.markX self.y = event.y - event.yStart + self.markY if (self.x \< common.right - mapW) then self.x = common.right - mapW end if (self.x \> common.left) then self.x = common.left end if (self.y \< common.bottom - mapH) then self.y = common.bottom - mapH end if (self.y \> common.top) then self.y = common.top end end return true end local btnZoomIn = widget.newButton ({ id = "point\_" .. math.random( 10000 ), defaultFile = "plus.png", overFile = "plus.png", width = 100, height = 100, onPress = function () print ( "map.width: " .. map.width .. " map.height: " .. map.height) end }) btnZoomIn.x = common.right - 70 btnZoomIn.y = common.centerY map:addEventListener("touch", map ) sceneGroup:insert( map ) sceneGroup:insert( btnZoomIn )

When you change the scale, the image display function does not work correctly

I purposely did not address scaling because it is a pain and a bit of work.

  1. You need to include the scale as part of the ‘onscreen’ calculation.

  2. You need to handle edge artifacts due to scaling.  When you scale and drag, the edge-to-edge images may develop gaps and artifacts.

  3. You need to write your own dragging code that accounts for scale.

Good day! Help optimize. currently, the load on the main mem memory: 2.28 mb, Texture mem 2.5 mb, while moving the image is very slow.

 function deg2num(lon, lat, zoom) local n = 2 ^ zoom local lon\_deg = tonumber(lon) local lat\_rad = math.rad(lat) local xtile = math.floor(n \* ((lon\_deg + 180) / 360)) local ytile = math.floor(n \* (1 - (math.log(math.tan(lat\_rad) + (1 / math.cos(lat\_rad))) / math.pi)) / 2) return xtile, ytile end function num2deg(x, y, z) local n = 2 ^ z local lon\_deg = x / n \* 360.0 - 180.0 local lat\_rad = math.atan(math.sinh(math.pi \* (1 - 2 \* y / n))) local lat\_deg = lat\_rad \* 180.0 / math.pi return lon\_deg, lat\_deg end local map = display.newGroup() local sliceW = 250 local sliceH = 250 local sliceA = 251 local z = 17 local minZ = 14 local maxZ = 17 local x, y = deg2num(55.92100, 55.06900, z) local x2, y2 = deg2num(56.08332, 55.00411, z) local rowCel = (y2 - y) local colCel = (x2 - x) local function doOnScreenFillTest ( self ) local x0 = self.x + self.parent.x + self.contentWidth local x1 = self.x + self.parent.x local y0 = self.y + self.parent.y + self.contentHeight local y1 = self.y + self.parent.y local onScreen = ( x0 \>= common.left and x1 \<= common.right ) and (y0 \>= common.top and y1 \<= common.bottom ) if( onScreen and self.lastFill == "fillT.png" ) then local path = system.pathForFile( self.imgPath, system.TemporaryDirectory ) local isFile = io.open( path, "r" ) if isFile then self.fill = { type = "image", filename = self.imgPath, baseDir = system.TemporaryDirectory } self.lastFill = self.imgPath io.close( isFile ) isFile = nil --print("SHOW", self.imgPath ) else isFile = nil local function networkListener( event ) if ( event.isError ) then print( "Network error - download failed: ", event.response ) elseif ( event.phase == "ended" ) then print( "Displaying response image file" ) self.fill = { type = "image", filename = event.response.filename, baseDir = event.response.baseDirectory } self.lastFill = event.response.filename end end network.download( self.imgLoadPath, "GET", networkListener, {progress = true}, self.imgPath, system.TemporaryDirectory ) --print("SHOW", self.imgPath ) end isFile = nil elseif( not onScreen and self.lastFill == self.imgPath ) then self.fill = { type = "image", filename = "fillT.png" } self.lastFill = "fillT.png" --print("HIDE", self.imgPath ) end end -- -- Create images from slices -- slices = {} local curX = 0 local curY = 0 for row = 1, 83 do local slice for col = 1, 118 do local imgLoadPath = "https://c.tile.openstreetmap.org/" ..z.. "/" ..(x + (col - 1)).. "/" ..(y + (row - 1)).. ".png" local imgPath = z .. "-" .. (x + (col - 1)) .. "-" .. (y + (row - 1)) .. ".png" slice = display.newRect( map, curX, curY, sliceW, sliceH ) slice.anchorX = 0 slice.anchorY = 0 slice.x = curX slice.y = curY curX = curX + sliceW slice.imgPath = imgPath slice.imgLoadPath = imgLoadPath slice.lastFill = slice.imgPath slice.doOnScreenFillTest = doOnScreenFillTest slices[slice] = slice slice:doOnScreenFillTest() end curX = 0 curY = curY + sliceH sliceH = sliceH + 1 end map.anchorX = 0 map.anchorY = 0 map.x = common.centerX - map.width / 2 map.y = common.centerY - map.height / 2 for key, val in pairs (slices) do val:doOnScreenFillTest() end function map:touch ( event ) for key, val in pairs (slices) do val:doOnScreenFillTest() end if event.phase == "began" then self.markX = self.x self.markY = self.y elseif event.phase == "moved" then self.x = event.x - event.xStart + self.markX self.y = event.y - event.yStart + self.markY if (self.x \< common.right - self.width) then self.x = common.right - self.width end if (self.x \> common.left) then self.x = common.left end if (self.y \< common.bottom - self.height) then self.y = common.bottom - self.height end if (self.y \> common.top) then self.y = common.top end end return true end map:addEventListener("touch", map )

You need to split it up into pieces and stitch them back together in a display group in Corona.

This example shows how I sliced up a 12000 x 8854 image into 30 slices then showed them in a draggable map.

It has the added feature of only ‘filling’ slices that are on-screen to save memory.

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2018/11/sliceNDice.zip

I used SSK for the dragger code and the FPS/Mem meters, but  the rest is pure Corona.

Yeah, it’s as Nick said. Loading an image of that size would require 2GB of texture memory and would be impossible to load as a single image. Your best bet would be to split it into pieces, as Nick also already stated. However, even still, if you were to split it into 1024x1024px images, you’d require approximately 9 x 11, i.e. 99 images. Each image would be 4MB, so you are again at ~396MB of texture memory used. This means that you’d have to implement a smart way of managing when and how you display those images in order to pull that off.

And just as I wrote my comment, Ed comes in with another fantastic demo of how it is done :smiley:

I’m very interested in knowing how the texture memory use in Ed’s example is only 13.51MB at its lowest, when loading a single 2000x1770 image should already require 2048 x 2048 x 4 / 1024 / 1024 = 16 MB of texture memory. Am I missing something here?

I’m just reporting what the system is telling me, but you’re right.  Something seems odd there.

Thank you very much for the answer! I thought about this way of displaying images, I’ll try your example. I am very pleased that this forum is a discussion and among the developers are not indifferent. I have one more question are there other examples of display images according to the technology roaminggamer.  Sorry for the late response, but we have different time zones.

Roaminggamer please tell me how to organize on Your example the restriction for the image goes beyond the visible part of the screen. For example: if the x coordinate is less -10321, the x coordinate is = -10321. I haven’t tried it yet, but as far as I understand map.does width contain the width of the entire map?

Hi.  I’m having trouble understanding your last couple of questions.

That said, you can find the API docs here:  https://docs.coronalabs.com/api/

Also, at the top of the page, are links to tutorials, guides, and other useful docs.

You’ll want to read more about display.*  properties and functions as a start.