2011-03-24 27 views
17

Tipik UIGraphicsBeginImageContextWithOptions yöntemiyle bir UIImage'a görüntülediğim UIView'im var. 2.0'lık bir ölçek kullanarak görüntü çıktısı her zaman ekranda görünecek olanın "retina ekranı" sürümüdür. Kullanıcının gerçek ekran çözünürlüğü.UIView Uiimage: ekran çözünürlüğünden daha mı yüksek?

UIView, görüntü oluşturma hem görüntü hem de metin (UIImages ve UILabels) içeriyor. Görüntü, işlenmiş UIImage'da tam çözünürlükte görünüyor ve harika görünüyor. Ancak UILabels, 1.0 ölçeğinde rasterleştirildi ve daha sonra 2.0'a yükseltildi ve bulanık metin elde edildi.

Yanlış yaptığım bir şey var mı, yoksa metni daha yüksek düzeyde net ve güzel hale getirmenin bir yolu var mı? Veya bunu daha iyi sonuçlara sahip olan UIGraphicsBeginImageContextWithOptions'ın ölçeklendirme parametresini kullanmaktan başka bir yolu var mı? Teşekkürler!

cevap

9

Bu çözüm, etiketin içeriklerini kalifiye hale getirmeden önce 2'ye değiştirip daha sonra geri yüklemenizdir. Bunu doğrulamak için bir proje hazırladım ve normal bir retina telefonunda (simülatör) 2x görüntü oluşturmaya gayret ediyorum. [Bir ortak yer varsa bunu bana bildirin koyabilirsiniz.]

EDIT: genişletilmiş kod subviews ve herhangi konteyner UIViews/unset

- (IBAction)snapShot:(id)sender 
{ 
    [self changeScaleforView:snapView scale:2]; 

    UIGraphicsBeginImageContextWithOptions(snapView.bounds.size, snapView.opaque, 2); 
    [snapView.layer renderInContext:UIGraphicsGetCurrentContext()]; 

    UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    imageDisplay.image = img; // contentsScale 
    imageDisplay.contentMode = UIViewContentModeScaleAspectFit; 

    [self changeScaleforView:snapView scale:1]; 
} 

- (void)changeScaleforView:(UIView *)aView scale:(CGFloat)scale 
{ 
    [aView.subviews enumerateObjectsUsingBlock:^void(UIView *v, NSUInteger idx, BOOL *stop) 
     { 
      if([v isKindOfClass:[UILabel class]]) { 
       v.layer.contentsScale = scale; 
      } else 
      if([v isKindOfClass:[UIImageView class]]) { 
       // labels and images 
       // v.layer.contentsScale = scale; won't work 

       // if the image is not "@2x", you could subclass UIImageView and set the name of the @2x 
       // on it as a property, then here you would set this imageNamed as the image, then undo it later 
      } else 
      if([v isMemberOfClass:[UIView class]]) { 
       // container view 
       [self changeScaleforView:v scale:scale]; 
      }  
     } ]; 
} 
+0

Bu, ancak bir UITableView yakalamaya çalışıyorsanız, her katmanı tek tek değiştirmek için bir acıdır. Tüm alt raporlar için tekrar tekrar değiştirmenin bir yolu yok mu? – charliehorse55

+1

Eh, bildiğim tek bir komut, ancak genişletilmiş kod not edin, çoğalır ve işin çoğunu yapar. Bir 2x görüntüye bir imageViews ayarlamamanız durumunda özel bir şey yapmanız gerekecektir (retina olmayan ekranlar için iyi çalışır, sadece render yaparken sistem için biraz daha çalışır. –

2

çift boyutu ile bir resme deneyin render ve sonra ölçekli görüntü oluşturun:

UIGraphicsBeginImageContextWithOptions(size, NO, 1.0); 
// Do stuff 
UImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

newImage=[UIImage imageWithCGImage:[newImage CGImage] scale:2.0 orientation:UIImageOrientationUp]; 

Burada: size = realSize * ölçek;

+0

emin değilim sizi anlamak ölçeğini ayarlamak için yürüyor diyorsun. Çalıştığım bir CGImage'm yok, UIView'im var, bu da bir UIImage'a dönüştürüyorum ... – DanM

+0

Düzenlendi. İstediğini yapmalı. – ssteinberg

+1

, sadece * herşeyi * ölçekleyecek mi? Yani şimdi hem metin * hem de * resim bulanık olacak mı? – DanM

0

Metin oluşturma bağlamında PDF oluşturma ile aynı garipliklerle uğraşıyorum. Görünümü oluşturan CALayer nesnelerinde bazı belgelenmiş özellikler olduğunu öğrendim. Belki de ilgili (alt) katmanın rasterleştirmesini ayarlama yardımcı olur.