views:

339

answers:

5

Hello,

I'm writing some map software for my smartphone and have hit a problem whereby I don't want to load all of the (large) image files into memory when only a portion will be displayed.

Is there a way to read only a subsection (the viewable portion) of a big image given that you know the x and y offsets and width? I know it's probably possibly to do it by reading the file a byte at a time but I'm not sure how to do this.

Thank you, Nico

+1  A: 

It's going to depend at least in part on what format(s) your images are saved in. If you have raw image files or bitmaps, it may be possible, but if your data is compressed in any manner, such as JPEG or PNG, it's going to be a lot more difficult to read just a subsection.

McWafflestix
A: 

If you truly don't want to ever load the full data into memory, you'll have to write your own IO routine that reads the file. For anything more complex than BMP, your decompression algorithm could get complicated.

280Z28
+1  A: 

Couldn't you cut the image up into sections beforehand?

Splitting it into many 256x256 pixel images means you'd only have to load a couple of them and stitch them back together on the viewable canvas. To name one implementation - google maps uses this technique.

gridzbi
I would go so far as to say this is *the* correct solution. Try to keep your image dimensions a power of two on each side (perhaps 256x256 or 512x512).
280Z28
@280Z28: ta for the correction
gridzbi
I already have the 256x256 chunks that make up the large image. I combined them into one image so that I could put it through gps map software which would convert it into a gps map with correct lat/long.I guess I could use the lat and long to find out which 256x256 chunk to load. I'll need to do some reading up on the maths though, it's why I delegated that bit to the gps map software in the first place :)
A: 

This is something I have done with bitmaps...

public BitmapCropBitmap(BitMap fullBitmap, Rectangle rectangle)
{
  return proBitmap.clone(fullBitmap, rectangle, fullBitmap.PixelFormat);
}
William Edmondson
which requires loading of the full bitmap first
Henk Holterman
A: 

If it's a BMP file, it shouldn't be that hard.

First you read the header from the file, if I recall correctly it's 44 bytes, but you can find that out from searching the web for a specification.

The header contains information like how many bytes there are per pixel, total width and height, how many bytes per scan line. Normally the bitmap is stored upside down, so you would calculate where in the file the first pixel of the bottom line was and skip to that location. Then you read the pixels you want from that line and skip to the correct pixel on the next line.

The FileStream class has what you need; a Read method for reading and a Seek method to skip to a given position.

Guffa
But you never want to store your resources on a memory-constrained device (or maybe ever) in an uncompressed format. It's a waste of space and is much slower to load from disk/flash.
280Z28
Thanks for all the responses! I'll take a look at this approach as well.Basically I've stitched together a large image from lots of 256x256 chunks.Then I had the problem of taking lat/long data from my gps reciever and deciding which image chunk to display on the screen. To do this I stitched the small images into one large one so that I could run it through a 3rd party tool that made a .map file with the correct lat/long transform applied (after calibrating with a handful of known points).I'll keep badgering away at it but I may just get lazy and use some existing maps instead of ma
ran out of space on that last comment. Thanks for all the feedback, I'll try by keeping the smaller chunks. Then the challenge will be to decide which ones to use based on the gps coords. I'll have to write some sort of transform from lat/long to pixels I imagine.