2013-12-11 26 views
3

Я пытаюсь создать объект, который может нарисовать часть большого изображения (например, 2048 x 1537) с помощью CGContextDrawImage (...). Он работает просто отлично, за исключением того, что он чрезвычайно размыт. Я использую «drawingController», который переопределяет drawLayer: InContext: как этотCGContextDrawImage рисует большие изображения очень размытым

-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{ 
    CGImageRef drawImage = CGImageRetain(imageToDraw); 
    if(drawImage) { 
     CGRect drawRect = CGRectMake(0, 0, 1024, 748);//Just hard coded to my window size for now. 
     CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); 
     CGContextDrawImage(ctx, drawRect, drawImage); 
    } 
    CGImageRelease(drawImage); 
} 

И это, как я настроил свой пользовательский хостинг изображений вид:

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code here. 
     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"large" ofType:@"jpg"]; 
     CGImageRef imageRef = [self createCGImageFromFilePath:filePath]; 


     drawingController = [[DrawingLayerController alloc] init]; 
     drawingController.imageToDraw = imageRef; 

     [self setWantsLayer:YES]; 
     imageLayer = [[CALayer alloc] init]; 
     imageLayer.frame = self.bounds; 
     imageLayer.drawsAsynchronously = YES; 
     imageLayer.delegate = drawingController; 
     [self.layer addSublayer:imageLayer]; 

     imageLayer.contentsRect = CGRectMake(0.5, 0.265452179, 0.5, 0.486662329); //Just an example contents rect. 
     imageLayer.drawsAsynchronously = YES; 

     [imageLayer setNeedsDisplay]; 
     [imageLayer displayIfNeeded]; 
    } 
    return self; 
} 

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

Hopefully the image doesn't become blurry when I upload it haha

Как вы можете видеть, изображение, полученное с помощью моего кода выглядит УЖАСНО. Что с этим связано?

Также, для полноты, я попытался использовать CATiledLayer для своего ImageLayer. Полученное изображение выглядит так же ужасно.

Замечание: код должен быть совместим с iOS и OSX, но я выполняю все свои тесты на OSX.

EDIT: Благодаря @Andrea, я добавил выше CGContextDrawImage (...) Следующий

CGFloat scale = MAX(1,MAX(CGImageGetWidth(drawImage)/drawRect.size.width,CGImageGetHeight(drawImage)/drawRect.size.height)); 

layer.contentsScale = scale; 
+0

Почему вы устанавливаете '[self setLayer: [CALayer layer]]'? – yurish

+0

Нет веской причины. Я удалил его. –

+0

Попробуйте установить CALayer.contentsScale на [UIScreen mainScreen] .scale – yurish

ответ

0

Я не знаю точно, для OSX, но я могу дать вам несколько советов.

  • Проверьте contentScale свойства, как указано в commets, я написал также question об этом, но я никогда не имел реальный ответ
  • Большинство времени размытости из-за удаление информации о пикселе, это требующий к системе для наложение сглаживания на изображение, я вижу, что вы установили contentsRect, с contentsGravity, возможно, изменили пропорцию и масштабирование изображения, превратив его в размытое. Здесь хороший answer.
  • Какой у вас контентГравити?
  • Держите его простым в первую очередь, вам действительно нужно рисовать async?

Надеюсь, это поможет.

+2

ContentScale 2.0 действительно действительно делает изображение более понятным. Я полностью потеряю, как это объяснить. Почему мне нужно использовать шкалу контента 2.0? Я загружаю изображение непосредственно из файла в CGImageRef, поэтому магия NSImage @ 2x не происходит, и я рисую экран без сетчатки. –

+0

Привет @ RagnarDanneskjöld Какое разрешение исходного изображения? – Andrea

+0

Hi @ RagnarDanneskjöld Разрешение изображения больше (в два раза), поэтому необходимо перерисовать слой в меньшем пространстве, поэтому, возможно, вам нужно установить некоторые параметры во время его рисования, попробовали ли вы с CGContextSetShouldAntialias (ctx, true); CGContextSetAllowsAntialiasing (ctx, true) ;. У меня была аналогичная проблема, и я решил установить параметр minificationFilter на kCAFilterTrilinear непосредственно на этом слое, но я напрямую настраивал изображение как содержимое слоя – Andrea

Смежные вопросы