Iphone 使用CATiledLayer显示以编程方式拆分为平铺的大型图像

Iphone 使用CATiledLayer显示以编程方式拆分为平铺的大型图像,iphone,ios,draw,tile,catiledlayer,Iphone,Ios,Draw,Tile,Catiledlayer,我在使用CATiledLayer时遇到了一个问题。。。我有一张大图,一张地图,是4726 x 2701。基本上,我需要把这张图片分成几块,可以放大来查看很多细节,但也可以一直放大来查看整个地图。使用我当前的实现,如果将scrollview的zoomlevel设置为1.0(最大zoomscale),但如果缩小平铺,则平铺将被错误地替换,则效果会非常好 此处zoomlevel设置为1.0。这张地图看起来很完美。 但是如果zoomlevel完全消失了(我相信是0.2),那么地图就乱七八糟了。我应该看

我在使用CATiledLayer时遇到了一个问题。。。我有一张大图,一张地图,是4726 x 2701。基本上,我需要把这张图片分成几块,可以放大来查看很多细节,但也可以一直放大来查看整个地图。使用我当前的实现,如果将scrollview的zoomlevel设置为1.0(最大zoomscale),但如果缩小平铺,则平铺将被错误地替换,则效果会非常好

此处zoomlevel设置为1.0。这张地图看起来很完美。

但是如果zoomlevel完全消失了(我相信是0.2),那么地图就乱七八糟了。我应该看到整个地图,而不仅仅是两块瓷砖

下面是我如何从大图中获取瓷砖的:

- (UIImage *)tileForScale:(CGFloat)scale row:(int)row col:(int)col {
     float tileSize = 256.0f;
     CGRect subRect = CGRectMake(col*tileSize, row * tileSize, tileSize, tileSize);
     CGImageRef tiledImage = CGImageCreateWithImageInRect([mapImage CGImage], subRect);
     UIImage *tileImage = [UIImage imageWithCGImage: tiledImage];
     return tileImage;
}
我显示的瓷砖与苹果在PhotoScroller应用程序中的显示一模一样

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGFloat scale = CGContextGetCTM(context).a;

    CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
    CGSize tileSize = tiledLayer.tileSize;
    tileSize.width /= scale;
    tileSize.height /= scale;

    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 tileForScale:scale row:row col:col];
            CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row,
                                     tileSize.width, tileSize.height);
            tileRect = CGRectIntersection(self.bounds, tileRect);

            [tile drawInRect:tileRect];
        }
    }
}
-(void)drawRect:(CGRect)rect{
CGContextRef context=UIGraphicsGetCurrentContext();
CGFloat scale=CGContextGetCTM(上下文).a;
CATiledLayer*平铺层=(CATiledLayer*)[自层];
CGSize tileSize=tiledLayer.tileSize;
tileSize.width/=比例;
tileSize.height/=刻度;
int firstCol=floorf(CGRectGetMinX(rect)/tileSize.width);
int lastCol=floorf((CGRectGetMaxX(rect)-1)/tileSize.width);
int firstRow=地板(CGRectGetMinY(rect)/tileSize.height);
int lastRow=地板((CGRectGetMaxY(rect)-1)/tileSize.height);
对于(int row=firstRow;row,在-(UIImage*)tileForScale:(CGFloat)scale row:(int)row col:(int)col中有泄漏

CGImageRef tiledImage=CGImageCreateWithImageInRect([mapImage CGImage],subRect)

不要忘记释放CGImageRef:CGImageRelease(tiledImage);

在-(UIImage*)tileForScale:(CGFloat)scale行:(int)行列:(int)列列列中有漏洞

CGImageRef tiledImage=CGImageCreateWithImageInRect([mapImage CGImage],subRect)


别忘了发布CGImageRef:CGImageRelease(tiledImage);

我认为在示例代码中存在一个错误,即比例设置不正确。 我有以下资料:

CGFloat scale = CGContextGetCTM(context).a;
scale = 1.0f / roundf(1.0f / scale);
if (scale == INFINITY) {
    scale = 1.0f;
}

我认为在示例代码中存在一个错误,即比例设置不正确。 我有以下资料:

CGFloat scale = CGContextGetCTM(context).a;
scale = 1.0f / roundf(1.0f / scale);
if (scale == INFINITY) {
    scale = 1.0f;
}

您的平铺层的
levelsOfDetail
属性的值是多少?您对所有比例使用相同的源图像,因此
levelsOfDetail
应设置为1I更新问题以反映细节级别。据我所知,您需要为每个细节级别提供不同的图像,并且您目前正在所有级别都使用同一个。我会手动分割图像,然后像Apple那样使用预渲染的平铺,但我没有这个选项。我必须在运行时使用代码将大型图像文件分割为较小的图像。你知道我应该如何正确地做到这一点吗?我应该停止说话并尝试你所说的。设置级别lsOfDetail到1工作得很好!:)您的平铺层的
levelsOfDetail
属性的值是多少?您对所有比例使用相同的源图像,因此
levelsOfDetail
应设置为1I更新问题以反映细节级别。据我所知,您需要为每个细节级别提供不同的图像,并且您目前正在所有级别都使用同一个。我会手动分割图像,然后像Apple那样使用预渲染的平铺,但我没有这个选项。我必须在运行时使用代码将大型图像文件分割为较小的图像。你知道我应该如何正确地做到这一点吗?我应该停止说话并尝试你所说的。设置级别lsOfDetail到1工作得很好!:)