2013-07-12 2 views
3

У меня есть CATiledLayer-backed UIScrollView, который отображает действительно большое изображение. То, что я хотел бы достичь, - это захватить этот вид в UIImage (использовать его в качестве фона для представления индикатора выполнения). Есть несколько проблем:iOS - CATiledLayer renderInContext: приводит к искажению изображения

  • на «100%» трансфокатор (вся картина видна), кажется, хорошо
  • если увеличить в Scrollview, некоторые из плиток искажаться (масштаб и/или смещение это плохо)
  • пытался Репрографический его с образцом PhotoScroller Apple, который почти работает, за исключением того, что захваченных изображений пикселизированным иногда
  • Я не писать код, так что я понятия не имею, как это исправить

Проверил другие StackOverflow записи относительно этого, но они не были много из помощи ...

код захвата изображения:

CGRect rect = [view bounds]; 
UIImage* img = nil; 

if ([view isKindOfClass:[UIScrollView class]]) 
{ 
    UIScrollView* scrollview = (UIScrollView*)view; 
    CGPoint contentOffset = scrollview.contentOffset; 

    UIGraphicsBeginImageContextWithOptions(rect.size, view.opaque, 0.0); 
    CGContextRef ctx = UIGraphicsGetCurrentContext(); 

    CGContextTranslateCTM(ctx, -contentOffset.x, -contentOffset.y); 
    [view.layer renderInContext:ctx]; 

    img = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
} 

И код плиточном зрения в DrawRect: метод:

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    if (self.clipContent) 
    { 
     CGContextSaveGState(context); 
     CGFloat color[4] = {1.0, 1.0f, 1.0f, 1.0f}; 
     CGContextSetFillColor(context, color); 
     CGContextFillRect(context, self.bounds); 

     CGRect clips[] = { 
      CGRectMake(self.bounds.size.width/2.0, 0, 
         self.bounds.size.height/2.0 , self.bounds.size.width/2.0) 
     }; 

     CGContextClipToRects(context, clips, sizeof(clips)/sizeof(clips[0])); 
    } 

    CGFloat scale = CGContextGetCTM(context).a; 
    CGSize tileSize = [_dataSource tileSize]; 

    double width = (double)tileSize.width/(double)scale;//pow(2.0, (int)log2(scale)); 
    double height = (double)tileSize.height/(double)scale;//pow(2.0, (int)log2(scale)); 

    int firstCol = floorf(CGRectGetMinX(rect)/width); 
    int lastCol = floorf((CGRectGetMaxX(rect) - 1)/width); 
    int firstRow = floorf(CGRectGetMinY(rect)/height); 
    int lastRow = floorf((CGRectGetMaxY(rect) - 1)/height); 

    for (int row = firstRow; row <= lastRow; row++) { 
     for (int col = firstCol; col <= lastCol; col++) { 
      UIImage* tileImage = [_dataSource tileForScale:scale row:row col:col]; 

      CGRect tileRect = CGRectMake(width * col, height * row, width, height); 
      tileRect = CGRectIntersection(rect, tileRect); 

      [tileImage drawInRect:tileRect]; 
     } 
    } 

    if (self.clipContent) 
     CGContextRestoreGState(context); 
} 

Любые идеи?

ответ

2

После большого количества проб и ошибок выяснилось, что сама реализация какао неполна, поэтому проблема не может быть решена.

С выходом прошивки 7 есть новый метод, хотя:

[view drawViewHierarchyInRect:rect afterScreenUpdates:YES]; 

(вместо renderInContext), и он работает (изображение несколько размыто, но тот приемлемый побочный эффект).

+0

Я не могу поблагодарить вас за это. Я боролся с неправильно сделанными моментальными снимками в течение нескольких часов, прежде чем нашел этот пост. –

+0

, но таким образом изображение искажено! его не в правильной форме. @Asylum –