2009-08-09 20 views
5

UIImageView ile gerçekten çok tuhaf bir sorunum var. Görüntüye eklediğim bir görüntü (bir RGB png) 45x45 pikselim var. Görüntüye eklendikten sonra görüntünün bulanık olduğunu görebiliyorum. İşte (solda) simülatörde aynı görüntü ve Xcode (sağ):UIImageView neden bulanık?

- (id) initWithImage:(UIImage*) image { 
    self = [super initWithImage:image]; 

    self.frame = CGRectMake(0, 0, 45, 45); 
    self.contentMode = UIViewContentModeScaleAspectFit; 

    self.quantity = 1; 
    if (self) { 
     self.label = [[UITextField alloc]initWithFrame:CGRectMake(0,40,45,25)]; 
     self.label.font = [UIFont systemFontOfSize:16]; 
     self.label.borderStyle = UITextBorderStyleNone; 
     self.label.enabled = TRUE; 
     self.label.userInteractionEnabled = TRUE; 
     self.label.delegate = self; 
     self.label.keyboardType = UIKeyboardTypeNumbersAndPunctuation; 
     self.label.textAlignment = UITextAlignmentCenter; 
    } 
    self.userInteractionEnabled = TRUE; 

    // Prepare 3 buttons: count up, count down, and delete 
    self.deleteButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    self.deleteButton.hidden = NO; 
    self.deleteButton.userInteractionEnabled = YES; 
    self.deleteButton.titleLabel.font = [UIFont systemFontOfSize:20]; 
    self.deleteButton.titleLabel.textColor = [UIColor redColor]; 
    [self.deleteButton setTitle:@"X" forState:UIControlStateNormal]; 
    [self.deleteButton addTarget:self action:@selector(deleteIcon:) forControlEvents:UIControlEventTouchUpInside]; 

    self.upCountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    self.upCountButton.hidden = NO; 
    self.upCountButton.userInteractionEnabled = YES; 
    [self.upCountButton setTitle:@"+" forState:UIControlStateNormal]; 
    [self.upCountButton addTarget:self action:@selector(addQuantity:) forControlEvents:UIControlEventTouchUpInside]; 

    self.downCountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    self.downCountButton.hidden = YES; 
    self.downCountButton.userInteractionEnabled = YES; 
    [self.downCountButton setTitle:@"-" forState:UIControlStateNormal]; 
    [self.downCountButton addTarget:self action:@selector(removeQuantity:) forControlEvents:UIControlEventTouchUpInside]; 
    return self; 
} 

böyle oluşturun:

alt text http://partywithvika.com/iconinsim.pngalt text http://partywithvika.com/iconinxcode.png

Bu initWithImage koduyla özel UIImageView sınıf var :

UIImage *desertIcon = [UIImage imageNamed:@"desert.png"]; 
IconObj *desertIconView = [[IconObj alloc] initWithImage:desertIcon]; 
desertIconView.center = CGPointMake(265,VERTICAL_POINT_ICON); 
desertIconView.type = [IconObj TYPE_DESERT]; 
[self.view addSubview:desertIconView]; 
[desertIconView release]; 

Görüntülenen görüntü neden bir dosyada saklanan dosyadan daha çok olurdu?

+0

Bu sorun muhtemelen ilgisi yoktur, ancak init metodu, 'öz = atama sonra eğer daha geleneksel olacağını [süper initWithImage: Görüntüyü]', denetlemek Kendinin sıfır olup olmadığı ve eğer öyleyse, hemen geri dönün. Eğer kendiliğinden geçilmezse, ya (1) ebeveynin başlatıcısı düzgün bir şekilde kendini başlatamazdı, ya da (2) bazı garip bellek durumundan dolayı (çok nadiren) geri dönen bir tahsis olabilir. İyi savunma programlama pratiği. –

+0

Not için teşekkürler, bunu deneyeceğim. –

cevap

0

Ekran piksellerinde IconObj görünümünüzü hizalamaya çalışın. Eğer gerçekten 45x45 ise, merkezi CGPointMake (x + 0.5f, y + 0.5f) gibi bir şeye ayarlamanız gerekir.

Ayrıca görüntü boyutunu piksel olarak iki kez kontrol etmelisiniz (ör. Preview.app Komut-I'de). Ben

contentMode = UIViewContentModeScaleAspectFit; 
+0

Nikolai, Yorumunuzda 'x' ve 'y' ile ne demek istediğini anlamadım. İlginç olan şey, UIImageView'ın aynı kodla daha büyük resim ile başlatılması durumunda çok keskin olmasıdır. –

+0

x ve y ile herhangi bir tam sayı koordinatını kastediyorum. Çerçeve, sınırlar ve görünümlerin merkezi özellikleri tüm koordinatlar için CGFloat tabanlı türleri kullanırken, görüntülerin ekrana pikselle hizalanması genellikle iyi bir fikirdir. –

1

bu sorunu vardı ve bana deli ediyordu. Bazı araştırmalardan sonra görüntünün çerçeveden daha küçük olduğu ve dolayısıyla ölçeklemenin bulanıklaştığı ortaya çıktı. Bir kez daha yüksek çözünürlüklü görüntüler koyduğumda problem gitti.

Görüntü boyutunuzun UIImageView çerçeve boyutunuzdan daha büyük olduğundan emin olun.

+0

Görüntü boyutunu iki kez kontrol etmenizi söyledim. –

+0

Nikolai, benim görüntüm 45x45 oldu ve UIImageView için çerçeve de 45x45 oldu. Bu kurulumu yanlış yorumlama potansiyeli görüyor musunuz? –

+1

Görüntünün piksellerini ekran piksellerine hizalamayı denediniz mi? –

3

ile tabii ki, 45x45 UIImageView içine büyük resmi yükleniyor yapıyor sona ne

8

Genel olarak, UIKit ile iPhone'da yaptığınız her şey piksel hizalanmış olmalıdır. Piksel hizalama ile ilgili sorunlar genellikle bulanıklık (bu özellikle metin ve resimlerle doğrudur) olarak tezahür eder. Bu yüzden bulanık görünüm bulduğumda, ilk olarak center özelliğini ayarlayıp ayarlamadığımı kontrol ediyorum. center'u ayarladığınızda, çerçevenin x, y, yükseklik ve genişliği o merkez noktanın etrafında ayarlanır ... sık sık kesirli değerler oluşturur.

Sen gösterildiği gibi çerçeve üzerinde CGRectIntegral kullanarak deneyebilirsiniz:

desertIconView.center = CGPointMake(265,VERTICAL_POINT_ICON); 
desertIconView.frame = CGRectIntegral(desertIconView.frame); 

Bu işe yarayabilir, ancak bunları yapmazsa, hiçbir değer fraksiyonel olmasını sağlamak için center özelliğini kullanmadan, elle frame ayarlamayı deneyin .

Düzenleme: Whoops! OP'nin kendi sorusunu cevapladığını farketmemişti ... Bunu zaten bilgi amaçlı olarak bırakacağım.

+1

Diğer cevapların çoğu (orijinal posterin yanı sıra) bunun bir piksel hizalama problemi olduğunu, bunun için +1 en temiz ve en genel amaç olduğunu kabul eder. çözüm – MrCranky

3

IconObj'iniz 45 piksel genişliğindedir. IconObj merkezinizi 265'e taşıyorsunuz, bu da çerçevesini yapıyor (242.5, VERTICAL_POINT_ICON - 25 * 0.5, 45, 25). Çerçeve parametresinin bir kısmı tam sayı değilse, görüntü her zaman bulanık olacaktır.

Çözüm, çerçeve parametresini kendiniz hesaplayın (merkez kullanmayın). Ve her zaman tamsayı yapın (NSInteger'e dökün, tavanı veya zemini kullanın).

desertIconView.frame = CGRectMake((NSInteger)(265 - 45*0.5), 
            (NSInteger)(VERTICAL_POINT_ICON - 25*0.5), 
            45, 25); 
1

Sadece aynı sorunu yaşadım. İlk önce gözlüklere ihtiyacım var mıydı?

Daha sonra tek bir sayı verdiğinizde bir görüntüyü (veya etiketi) ortalamanın mümkün olmadığını farkettim. Görüntünüzü ör. Eğer onu ortalamak ve keskin kalmak istiyorsanız 46 * 46.

Ya da 45 * 45'de bırakabilirsiniz ancak görüntünüzün sağa 1 piksel sağa mı yoksa 1 piksel sola mı karar verdiğine karar vermeniz gerekir. (ya da bulanık bırakın).

ofset sorun için
0

komple kaynak:

contentImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; 

    UIImage *cImage = [UIImage imageNamed:image]; 
    self.contentImage.image = cImage; 

    [self.contentImage setFrame:CGRectMake(0, 0, cImage.size.width, cImage.size.height)]; 

    CGFloat offset = 0.0f; 

    if (((int)cImage.size.width % 2) && ((int)cImage.size.height % 2)) { 
    offset = 0.5f; 
    } 

    [self.contentImage setCenter:CGPointMake(256.0f + offset, 256.0f + offset)];