问题:
我必须渲染一个 7148x15000px 的大图像(自定义地图),所以我四处寻找有用的东西,我找到了 BitmapSlice,但问题是我第一次运行应用程序(在设备和模拟器上)几个切片未正确加载,我看到带有大黑洞的图像。
代码:
BitmapSliceViewController.h
#import <UIKit/UIKit.h>
@interface BitmapSliceViewController : UIViewController<UIScrollViewDelegate>
@property (nonatomic, retain) UIImageView *_zoomView;
@property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
- (void)saveTilesOfSize:(CGSize)size forImage:(UIImage*)image toDirectory
(NSString*)directoryPath usingPrefix:(NSString*)prefix;
@end
BitmapSliceViewController.m
#import "BitmapSliceViewController.h"
#import "TileView.h"
@implementation BitmapSliceViewController
@synthesize scrollView;
- (void)dealloc
{
[super dealloc];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *directoryPath = [paths objectAtIndex:0];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *big = [UIImage imageNamed:@"map.jpg"];
[self saveTilesOfSize:(CGSize){256, 256} forImage:big toDirectory:directoryPath usingPrefix:@"map_"];
dispatch_async(dispatch_get_main_queue(), ^{
[scrollView setNeedsDisplay];
});
});
TileView *tv = [[TileView alloc] initWithFrame:(CGRect){{0,0}, (CGSize){7148,15000}}];
[tv setTileTag:@"map_"];
[tv setTileDirectory:directoryPath];
[scrollView addSubview:tv];
[scrollView setContentSize:(CGSize){7148,15000}];
[scrollView setDelegate:self];
}
- (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 = UIImageJPEGRepresentation([UIImage imageWithCGImage:tileImage], 1);
CGImageRelease(tileImage);
NSString *path = [NSString stringWithFormat:@"%@/%@%d_%d.png",
directoryPath, prefix, x, y];
[imageData writeToFile:path atomically:NO];
}
}
}
@end
平铺视图.h
@interface TileView : UIView
@property (nonatomic, copy) NSString *tileTag;
@property (nonatomic, copy) NSString *tileDirectory;
- (UIImage*)tileAtCol:(int)col row:(int)row;
@end
瓦片视图.m
#import "TileView.h"
@implementation TileView
@synthesize tileTag;
@synthesize tileDirectory;
+ layerClass
{
return [CATiledLayer class];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (!self) return nil;
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)drawRect:(CGRect)rect {
//CGContextRef context = UIGraphicsGetCurrentContext();
CGSize tileSize = (CGSize){256, 256};
int firstCol = floorf(CGRectGetMinX(rect) / tileSize.width);
int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize.width);
int firstRow = floorf(CGRectGetMinY(rect) / tileSize.height);
int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize.height);
for (int row = firstRow; row <= lastRow; row++) {
for (int col = firstCol; col <= lastCol; col++) {
UIImage *tile = [self tileAtCol:col row:row];
if (tile)
{
CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row, tileSize.width, tileSize.height);
tileRect = CGRectIntersection(self.bounds, tileRect);
[tile drawInRect:tileRect];
// [[UIColor whiteColor] set];
// CGContextSetLineWidth(context, 6.0);
// CGContextStrokeRect(context, tileRect);
}
}
}
}
- (UIImage*)tileAtCol:(int)col row:(int)row
{
NSString *path = [NSString stringWithFormat:@"%@/%@%d_%d.png", tileDirectory, tileTag, col, row];
return [UIImage imageWithContentsOfFile:path];
}
@end
这是应用程序的主要代码,您可以从文章顶部链接的站点下载整个示例。
正如我所说,主要问题是在应用程序的第一次运行中失败的某些切片的渲染,其他运行似乎正常工作。
稍作修改- (UIImage*)tileAtCol:(int)col row:(int)row
- (UIImage*)tileAtCol:(int)col row:(int)row
{
NSString *path = [NSString stringWithFormat:@"%@/%@%d_%d.png", tileDirectory, tileTag, col, row];
UIImage *img = [UIImage imageWithContentsOfFile:path];
if (img) {
NSLog(@"good");
}
else {
NSLog(@"bad");
}
return img;
}
问题似乎在这里...
有什么想法可以解决吗?
提前致谢