I am writing an app which would tile the images 256 * 256 and write those tile files back in the directory. I am updating my URL each time if there are any updates and tile those images back and store in the iphone folder. I am worried about two main things :
1) Memory consumption — will the memory consumption for 5 images of size 200 KB a lot ?
2) How fast I can process my app if I have to tile 5 different URL with images at the same time ?
I have written a code to tile and save in the directory for one URL and would like to do the same for 5 URLs. Is it recommended to go with this approach or if anyone has a different approach?
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *URLString = @"http://www.abc.com/abc.html?event=123";
NSURL *url = [[NSURL alloc] initWithString:URLString];
NSData * dataImage = [NSData dataWithContentsOfURL:url];
NSString *directoryPath = [[NSBundle mainBundle] bundlePath];
UIImage *big = [UIImage imageWithData:dataImage];
[self saveTilesOfSize:(CGSize){256,256} forImage:big toDirectory:directoryPath usingPrefix:@"image_124_"];
TileView *tv = [[TileView alloc] initWithFrame:(CGRect){{0,0}, (CGSize){5000,5000}}];
[tv setTileTag:@"image_110_"];
[tv setTileDirectory:directoryPath];
[scrollView addSubview:tv];
[scrollView setContentSize:(CGSize){5000,5000}];
}
- (void)saveTilesOfSize:(CGSize)size
forImage:(UIImage*)image
toDirectory:(NSString*)directoryPath
usingPrefix:(NSString*)prefix
{
CGFloat cols = [image size].width / size.width;
CGFloat rows = [image size].height / size.height;
int fullColumns = floorf(cols);
int fullRows = floorf(rows);
CGFloat remainderWidth = [image size].width -
(fullColumns * size.width);
CGFloat remainderHeight = [image size].height -
(fullRows * size.height);
if (cols > fullColumns) fullColumns++;
if (rows > fullRows) fullRows++;
CGImageRef fullImage = [image CGImage];
for (int y = 0; y < fullRows; ++y) {
for (int x = 0; x < fullColumns; ++x) {
CGSize tileSize = size;
if (x + 1 == fullColumns && remainderWidth > 0) {
// Last column
tileSize.width = remainderWidth;
}
if (y + 1 == fullRows && remainderHeight > 0) {
// Last row
tileSize.height = remainderHeight;
}
CGImageRef tileImage = CGImageCreateWithImageInRect(fullImage,
(CGRect){{x*size.width, y*size.height},
tileSize});
NSData *imageData = UIImagePNGRepresentation([UIImage imageWithCGImage:tileImage]);
NSString *path = [NSString stringWithFormat:@"%@/%d.png",
directoryPath, prefix];
[imageData writeToFile:path atomically:NO];
}
}
}
I have implemented solution for the similar problem(the difference is, I was not saving them in directory, those were for display purpose only.), with different approach.
In my problem,
I have 84 images of 250x250 dimension with size 8KB each( I added them onscrollViewand on scrolling I load them, a bit similar to google maps, but more smooth). At first I was using the same approach as yours, but performance was problem. So, I used asynchornous loading concept. I wrote an UIImageView subclass with connectiond delegates, so the UIImageView subclass was responsible for loading it’s image. And as loading is asynchronous so performance is far better.As you asked
1) Memory consumption — will the memory consumption for 5 images of size 200 KB a lot?
Ans: 5x200KB = 1MB ~ 1.2MB or so(so you will need that much memory for displaying, if you have that much amount of memory then you should not worry.).. in my case 84x8KB = 672 ~ 900KB(as I was using some additional things like activity indicator for each imageview).2) How fast I can process my app if I have to tile 5 different URL with images at the same time ?
Ans: As you are loading it in viewDidLoad … or in main thread then performance will be an issue(blocking may happen, as I am not completely sure whether you are using threads or not).Quick suggestion:
CODE :
TileImageView.hTileImageView.mSo, If you use above code then only thing you have to do is to add the object of TileImageView and just call method
-(void) startImageDownloading:(NSString *)pRequestURL.Update :
//like this I add 84 images in a 2D shape( 12 x 7) grid … and once Images are added I set scrollView’s contentSize as per complete grid size.
..later in code when user scroll’s and other imageviews come in visibility.I use following code…
TileImageView *loadableImageView = (TileImageView *)[myImageScrollView viewWithTag:];
[loadableImageView startImageDownloading:];
I do not need to do anything in
drawRect: , as I have no need to do custome drawing.For Image names you can use tag property from
imageView, but if you need some different name that are more like string then you can put another property inimageViewfor image name and set it while adding the image view. for saving data you can call your method once the image is downloaded indidFinishLoadingmethod ofTileImageView, where you can use that name.SECODN UPDATE
How I add
TileImageViewonScrollViewAnd in
ScrollViewDelegatemethod.And this is how
createAndSendScrollRequestis implemented.Thanks,