iPhone OS 3.1.3'te bir CATiledLayer kullanmak ve bunu -(void)drawLayer:(CALayer *)layer inContext:(CGContext)context
numaralı çizimde yalnızca coregraphics ile yapmak zorundayım.CoreGraphics ile CATiledLayer Çizim CGContextDrawImage
Şimdi iPhone'da koordinat sistemi çevirdi ait sorunlarla ve dönüşümleri kullanarak bunu düzeltmek için nasıl bazı öneriler vardır:
Benim sorundur Bunu işe alamıyorum. PhotoScroller örnek kodunu kullanmaya ve çizim yöntemini yalnızca coregraphics çağrılarıyla değiştirmeye başladım. Eğer ben bir Ölçek koordinat sistemi tersine çevirmek için dönüşümü kullanıyorum ve bir çeviri sol alt köşesine kökeni kaydırmaya dönüşümü görebileceğiniz gibi bu
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context {
CGContextSaveGState(context);
CGRect rect = CGContextGetClipBoundingBox(context);
CGFloat scale = CGContextGetCTM(context).a;
CGContextConcatCTM(context, CGAffineTransformMakeTranslation(0.f, rect.size.height));
CGContextConcatCTM(context, CGAffineTransformMakeScale(1.f, -1.f));
CATiledLayer *tiledLayer = (CATiledLayer *)layer;
CGSize tileSize = tiledLayer.tileSize;
tileSize.width /= scale;
tileSize.height /= scale;
// calculate the rows and columns of tiles that intersect the rect we have been asked to draw
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++) {
// if (row == 0) continue;
UIImage *tile = [self tileForScale:scale row:row col:col];
CGImageRef tileRef = [tile CGImage];
CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row,
tileSize.width, tileSize.height);
// if the tile would stick outside of our bounds, we need to truncate it so as to avoid
// stretching out the partial tiles at the right and bottom edges
tileRect = CGRectIntersection(self.bounds, tileRect);
NSLog(@"row:%d, col:%d, x:%.0f y:%.0f, height:%.0f, width:%.0f", row, col,tileRect.origin.x, tileRect.origin.y, tileRect.size.height, tileRect.size.width);
//[tile drawInRect:tileRect];
CGContextDrawImage(context, tileRect, tileRef);
// just to draw the row and column index in the tile and mark the origin of the tile with a red line
if (self.annotates) {
CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor]CGColor]);
CGContextSetLineWidth(context, 6.0/scale);
CGContextStrokeRect(context, tileRect);
CGContextSetStrokeColorWithColor(context, [[UIColor redColor]CGColor]);
CGContextMoveToPoint(context, tileRect.origin.x, tileRect.origin.y);
CGContextAddLineToPoint(context, tileRect.origin.x+100.f, tileRect.origin.y+100.f);
CGContextStrokePath(context);
CGContextSetStrokeColorWithColor(context, [[UIColor redColor]CGColor]);
CGContextSetFillColorWithColor(context, [[UIColor whiteColor]CGColor]);
CGContextSelectFont(context, "Courier", 128, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetShouldAntialias(context, true);
char text[30];
int length = sprintf(text,"row:%d col:%d",row,col);
CGContextSaveGState(context);
CGContextShowTextAtPoint(context, tileRect.origin.x+110.f,tileRect.origin.y+100.f, text, length);
CGContextRestoreGState(context);
}
}
}
CGContextRestoreGState(context);
}
benziyor. Görüntüler doğru bir şekilde çizilir, ancak yalnızca ilk sıradaki karolar çizilir. Çeviri işleminde veya karoların koordinatlarının hesaplanma şekliyle ilgili bir sorun olduğunu düşünüyorum. Tüm bu dönüşümler ile biraz karıştı
:
Bu gibi görünüyor nasıl.
Bonus soru: Retina görüntü resimlerinin çekirdek grafiklerde nasıl ele alınır?
DÜZENLEME: o görüntüler sağlamak için sadece örnek kod orijinal yöntemini aldı Retina görüntüsü üzerinde çalışmaya almak için: Ekranın ölçekli Çekirdek beri göz ardı edilir Prensip olarak
- (UIImage *)tileForScale:(CGFloat)scale row:(int)row col:(int)col
{
// we use "imageWithContentsOfFile:" instead of "imageNamed:" here because we don't want UIImage to cache our tiles
NSString *tileName = [NSString stringWithFormat:@"%@_%d_%d_%d", imageName, (int)(scale * 1000), col, row];
NSString *path = [[NSBundle mainBundle] pathForResource:tileName ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:path];
return image;
}
Grafikler piksel noktasında değil noktasında çalışıyor, bu nedenle daha fazla piksel çizmek istendiğinde, ekranı doldurmak için daha fazla CATiledLayer (veya alt tabaka) kullanılıyor.
Teşekkür Thomas
Cevabınız için teşekkür ederiz. UIImage yönteminin doğru çözünürlüğü alması gerektiğinden retina ekranı için doğru görüntüyü almak için [[UIImage imageNamed: @ "imageName"] CGImage] yöntemini kullanamazsınız? – GorillaPatch
Gerçekten güzel çalışıyor! Teşekkürler! Ben temelde görüntü karoları sağlamak için örnek koddan alınan yöntemi kullanıyorum, bu yüzden bir retina ekranda sadece görüntüyü çizmek için farklı bir yakınlaştırmada daha fazla fayans görüntüler. Yöntemi asıl soruya ekledim. – GorillaPatch