1

CATiledLayer の使用で問題が発生しています... 4726 x 2701 の大きな画像、マップがあります。基本的に、この画像をタイルに分割し、ズームインして多くの画像を表示できるようにする必要があります。詳細だけでなく、ズームアウトしてマップ全体を表示することもできます。私の現在の実装を使用すると、スクロールビューのズームレベルが 1.0 (最大ズームスケール) に設定されている場合は完全に機能しますが、ズームアウトするとタイルが正しく置き換えられません。

ここではズームレベルが 1.0 に設定されています。マップは完璧に見えます。 ここに画像の説明を入力

しかし、ズームレベルが完全に外れている場合 (0.2 だと思います)、マップはすべて台無しになります。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;
}

Apple が 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];
        }
    }
}

また、詳細レベルを設定しているコードは次のとおりです。これは、画像に対して 4 を返します。

- (id)initWithImageName:(NSString *)name andImage:(UIImage*)image size:(CGSize)size {
    self = [super initWithFrame:CGRectMake(0, 0, size.width, size.height)];
    if (self) {
        _imageName = [name retain];
        mapImage = [image retain];

        CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
        tiledLayer.levelsOfDetail = [self zoomLevelsForSize:mapImage.size];
    }
    return self;
}
- (NSUInteger)zoomLevelsForSize:(CGSize)imageSize {
    int zLevels = 1;
    while(YES) {
        imageSize.width /= 2.0f;
        imageSize.height /= 2.0f;
        if(imageSize.height < 256.0 || imageSize.width < 256.0) break;
        ++zLevels;
    }
    return zLevels;
}

タイルのサイズとズームスケールに関係があると思いますが、問題を解決する方法がわかりません。Google で問題の解決策が見つからないようです。どんな助けでも素晴らしいでしょう!:)

4

2 に答える 2

1

- (UIImage *)tileForScale:(CGFloat)scale row:(int)row col:(int)col にリークがあります。

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

CGImageRef を解放することを忘れないでください: CGImageRelease(tiledImage);

于 2013-02-07T21:03:41.913 に答える
0

サンプル コードでスケールが正しく設定されていないバグがあると思います。私は次のものを持っています:

CGFloat scale = CGContextGetCTM(context).a;
scale = 1.0f / roundf(1.0f / scale);
if (scale == INFINITY) {
    scale = 1.0f;
}
于 2015-05-29T19:39:20.993 に答える