moagrius / TileView

TileView is a subclass of android.view.ViewGroup that asynchronously displays, pans and zooms tile-based images. Plugins are available for features like markers, hotspots, and path drawing.
MIT License
1.46k stars 335 forks source link

Can't load tile image from internal storage #509

Closed michaelneuf closed 5 years ago

michaelneuf commented 5 years ago

Using TileView 3.0.1, I tried to load tile images from internal storage but it doesn't seems to work. My initialization code is:

.setSize(4000, 6000)
.setTileSize(256)
.defineZoomLevel(2, "/storage/emulated/0/Android/data/tileview.demo/files/3-%1$d-%2$d.jpg")
.defineZoomLevel(1, "/storage/emulated/0/Android/data/tileview.demo/files/4-%1$d-%2$d.jpg")
.defineZoomLevel(0, "/storage/emulated/0/Android/data/tileview.demo/files/5-%1$d-%2$d.jpg")
.setStreamProvider(new StreamProviderFiles())
.build();

Checking the source code of Tile class, I noticed that an exception was raised in decode() on stream.reset() => java.io.IOException: mark/reset not supported

I managed to avoid this error wrapping the FileInputStream into a BufferedInputStream or resetting the stream using mStreamProvider.getStream(mColumn, mRow, context, mDetail.getData()); again but a new problem appeared.

Tiles are now visible but there is random glitch on my map and I noticed this kind of errors in logcat:

D/skia: libjpeg error 105 <  Ss=0, Se=63, Ah=0, Al=0> from Incomplete image data
D/skia: libjpeg error 116 <Corrupt JPEG data: 6593 extraneous bytes before marker 0xd9> from output_message
D/skia: libjpeg error 51 <JPEG datastream contains no image> from output_message
D/skia: libjpeg error 51 <JPEG datastream contains no image> from setjmp

Using the demo project with my custom images in asset folder works fine so I am sure that my images are fine.

Changing this solve the problem:

public TileRenderExecutor() {
    this(1);   //instead of Runtime.getRuntime().availableProcessors()
}

but it's obviously not a good solution.

Thanks for your help.

moagrius commented 5 years ago

what's mStreamProvider look like?

michaelneuf commented 5 years ago

It's in Tile class in decode() method. Instead of stream.reset(), I've done:

stream.close();
stream = mStreamProvider.getStream(mColumn, mRow, context, mDetail.getData());
moagrius commented 5 years ago

the StreamProvider is an interface. You need to give the program instructions on how to get a Stream. The default is for it to get the stream from a file in assets.

michaelneuf commented 5 years ago

I have used this stream provider which use FileInputStream: .setStreamProvider(new StreamProviderFiles())

moagrius commented 5 years ago

hm. i think you probably need to get the path to the SD card programmatically since you won't be sure it's always that same path on every device...

michaelneuf commented 5 years ago

Yeah sure, that's just for test purpose. I think the problem is easy to reproduce, you just have to try the demo app using tiles from sdcard instead of assets.

moagrius commented 5 years ago

oh hm ok will do

p-lr commented 5 years ago

Maybe unrelated to this issue, but I recently had a hard time to do the same thing. Pretty sure not related to TileView v2 which I'm still using (but not for long). It was a permission issue and to this day I still can't make it work with tiles in a folder of my choice in the SD card (haven't tested though if tiles are located inside the folder that Android allocates to the app if the SD card is used as an extension of the internal memory).

moagrius commented 5 years ago

well definitely seems like something i should try and verify then

moagrius commented 5 years ago

i can confirm similar issues. i'm not getting tiles to render at all, yet the streams are fine and i'm not getting any exceptions at all. i can even see the bytes on the streams, they're just not decoding (presumably).

i'll look into this and try to get a patch soon. thanks for the notification. if in your experimentation you find another fix, even if it doesn't seem great going forward, can you please post back here so I can narrow down the source and try to find a reasonable patch? thanks again

moagrius commented 5 years ago

@michaelneuf also, if you're open to a fairly random attempt at a fix, try your solution, but without the this(1) and instead synchronize Tile.decode... Maybe also try different cache policies (specifically, i'd try DiskCachePolicy.CACHE_NONE).

moagrius commented 5 years ago

hm so apparently it's something today with stream carets for local files. i'm getting "Mark was invalidated". This was apparently a big thing during the old UIL days with similar stream handling around local files. I've got to shut down for now, but I feel like this is a solvable problem, and definitely a bug introduced when moving from Bitmaps to Streams. I hope to have this solved soon, and will keep this thread updated. Off for now

michaelneuf commented 5 years ago

Thanks a lot for your help !

moagrius commented 5 years ago

Of course!

On Tue, Apr 30, 2019, 5:30 PM michaelneuf notifications@github.com wrote:

Thanks a lot for your help !

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/moagrius/TileView/issues/509#issuecomment-488138965, or mute the thread https://github.com/notifications/unsubscribe-auth/AAFLHIDCUK5FDF7Q6JLS7F3PTDB65ANCNFSM4HJECBCQ .

moagrius commented 5 years ago

@michaelneuf i have a version that works, but it's not really something that I can post a "fix" for here (the TLDR is that I let Picasso do the work, and am probably going to revert to BitmapProvider instead of StreamProviders, and let the image libraries do the heavy lifting around sampling and caching).

That said, i'm very close to releasing v4 (which is really just the production release of v3, with bug fixes like this one, but a change to namespace which requires a major version change according to semver). I'll post here when that's available. Thanks for pointing out the bug and the decent feedback to narrow down the issue.

Leaving the issue open until V4 is available; assigning label.

moagrius commented 5 years ago

@michaelneuf so i definitely have a fix and as i said it's in v4, but i'm still resolving things with jcenter, so i haven't made v4 public yet. if you can wait, then no problem - i hope to have this resolved as soon as possible.

otherwise, i have it in a temp repo, and you can use it in build.gradle by including the bintray URL, or i can walk you through the fix and you can import and modify whatever version you were using. let me know if either of those would be helpful, or if you're ok to wait for v4 to get linked on jcenter.

michaelneuf commented 5 years ago

Nice, it's a good news. I'll wait for the v4, it's not urgent for me. Thanks again :)

moagrius commented 5 years ago

NP!

On Fri, May 3, 2019 at 3:12 PM michaelneuf notifications@github.com wrote:

Nice, it's a good news. I'll wait for the v4, it's not urgent for me. Thanks again :)

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/moagrius/TileView/issues/509#issuecomment-489225219, or mute the thread https://github.com/notifications/unsubscribe-auth/AAFLHIFQGRELZDMSTWDJP4DPTSMBTANCNFSM4HJECBCQ .

moagrius commented 5 years ago

Version 4 is out, including a demo with files in both SD card and internal store

Closing fixed.