java - Zooming and loading very large TIFF file -
i have large hi-res map want use in application (imagesize around 80 mb).
i know following:
- how can load image best way possible? know take seconds load image (which ok) notify user of progress. use determined mode , show in sort of
jprogressbar
user. should reflect number of bytes have been loaded or that. there image loading method can provide functionality (likeimageio.read()
)? - because map of high resolution offer user scroll zoom in , out. how can best way? know fact rescaling
bufferedimage
standard way take long time such big file. there efficient way of doing this?
thank input!
kind regards,
héctor van den boorn
p.s. image drawn on canvas of jpanel.
hi andrew, thank help; worked out , loading quick. without expertise , explanation have still been working on you've earned bounty fair , square.
what did following; using imagemagick created multiple images of different resolution , @ start of execution load smallest res. image. rest loaded in seperate threads execution not stalled. using information provided me use appropriate images when zooming in or out. i'm bit sceptical of using tiles because need draw own images on top of map , couldn't find paint function in external jar told me use, ended using simple; when zooming or panning rescale mode set fast , when you're not zooming or panning rescale set smooth pixel-perfect images (just suggested), turns out fast enough , don't need tiles (altough see larger images necesarry , understand information you've given me).
so again , working :)
there 2 approaches should (simultaneously) take:
- downscaling image various sizes. should downscale image @ series of lower resolutions (1/2, 1/4, 1/8, etc until image largest screen resolution). when user first opens image, show lower resolution image. load fast , allow user pan. when user zooms in, use higher resolution image. can use imagemagick this: http://www.imagemagick.org/usage/resize/
- tile larger images. breaks down single, large image large number of small images in grid pattern. when user zooms in on area, compute tiles user looking at, , render them, not other areas of image. can use imagemagick split image tile, eg imagemagick. correct way dice image sub-tiles. documentation http://www.imagemagick.org/usage/crop/#crop_tile
(providing cache of appropriately sized , tiles images allows googleearth , countless other mapping applications, render fast, yet zoom map @ incredibly high resolution)
once have tiles, can use 1 of several engines in java:
there may others well.
you can implement arbitrary zooming (suitable pinch-to-zoom or similar) within framework. within zoom limits allow, algorithm like:
- for zoom level chosen user, choose closest higher resolution cache. example, if have 100%, 50%, 25% , 12.5% tiles, , user chooses 33% zoom, select 50% tiles
- set layout tiles tile squares have correct size chosen zoom (this might single tile @ lowest zoom levels). example, @ 33% zoom using 50% tiles, tiles being 100 pixels square, grid 67 pixel squares
- individually load , scale tile images fit screen (this can multi-threaded works on modern cpu architectures)
there couple of points note:
- the scaling algorithm changes when reach greatest resolution have tiles for.
- up 100% zooming image, use bilinear or bicubic scaling. provides excellent appearance photographs little jaggedness
- above 100%, want show pixels, nearest-neighbour might choice
- for higher fidelity, use higher scale tile , downscale > 50%. example, suppose have tiles prepared @ 100%, 50%, 25% , 12.5%. show 40% zoom, don't scale down 50% tiles; instead use 100% tiles , scale them down 40%. useful:
- if images textual or diagrams (i.e. raster images containing many straight lines). scaling these type of images produce nasty artefacts if don't oversample
- if need high fidelity on photographic-style images
- if need render preview of zoom (eg while user still pinching-and-zooming), grab screenshot @ start of gesture , zoom that. matters more animation smooth zoom preview pixel-perfect.
- selection of right size of tile important. large tiles (<1 per screen) slow render. small tiles creates other overheads , produces nasty rendering artefacts see screen filling randomly. compromise between performance , complexity make tiles quarter of full-screen size.
when using these techniques, images should load faster , progress bar not important. if is, need register iioreadprogresslistener on imagereader:
from javadoc:
an interface used imagereader implementations notify callers of image , thumbnail reading methods of progress.
this interface receives general indications of decoding progress (via imageprogress , thumbnailprogress methods), , events indicating when entire image has been updated (via imagestarted, imagecomplete, thumbnailstarted , thumbnailcomplete methods). applications wish informed of pixel updates happen (for example, during progressive decoding), should provide iioreadupdatelistener.
Comments
Post a Comment