2009-08-09 11 views
5

Ho un problema davvero strano con UIImageView. Ho un'immagine (una RGB png) 45x45 pixel che aggiungo alla vista. Vedo che l'immagine è sfocata dopo l'aggiunta alla vista. Ecco la stessa immagine nel simulatore (a sinistra) e in Xcode (a destra):Perché la mia UIImageView è sfocata?

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

ho lezione UIImageView personalizzato con questo codice initWithImage:

- (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; 
} 

creo come questo :

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]; 

Perché l'immagine visualizzata deve essere uguale a quella memorizzata in un file?

+0

Questo è probabilmente correlato al problema, ma il metodo init sarebbe più convenzionale, se, dopo l'assegnazione 'auto = [super initWithImage: Immagine]', si controlla se il sé è pari a zero, e se lo è, torna immediatamente a zero. Se self se mai nullo, è perché (1) l'inizializzatore del genitore non può inizializzarsi correttamente, o (2) alloc restituito nil a causa di alcune strane condizioni di memoria (estremamente rare). È una buona pratica di programmazione difensiva. –

+0

Grazie per la nota, ci proverò. –

risposta

0

Prova ad allineare la tua vista IconObj a pixel dello schermo. Se è veramente 45x45 allora dovresti impostare il centro su qualcosa come CGPointMake (x + 0.5f, y + 0.5f).

È inoltre necessario ricontrollare le dimensioni dell'immagine in pixel (ad esempio in Anteprima.app Comando-I).

+0

Nikolai, non ho capito cosa intendi con 'x' e 'y' nel tuo commento. La cosa interessante è che UIImageView è molto nitido se inizializzato con un'immagine più grande con lo stesso codice. –

+0

Con xey si intendono tutte le coordinate intere. Mentre le proprietà frame, bound e center delle viste usano i tipi basati su CGFloat per tutte le coordinate, di solito è una buona idea allineare i pixel allo schermo. –

1

Quello che ho finito per fare è di caricare più grande immagine in 45x45 UIImageView, naturalmente, con

contentMode = UIViewContentModeScaleAspectFit; 
+0

Ti ho detto di ricontrollare la dimensione dell'immagine. –

+0

Nikolai, la mia immagine era 45x45 e il frame per UIImageView era anche 45x45. Dove vedi un potenziale per interpretare male questa configurazione? –

+1

Hai provato ad allineare i pixel dell'immagine ai pixel dello schermo? –

3

Ho avuto questo problema e mi stava guidando dadi. Dopo alcune indagini, ho scoperto che la mia immagine era più piccola della cornice, e quindi l'ingrandimento lo offuscava. Una volta che ho messo le immagini ad alta risoluzione il problema è scomparso.

Assicurarsi che la dimensione dell'immagine sia maggiore della dimensione del frame UIImageView.

8

In generale, tutto ciò che fai su iPhone con UIKit deve essere allineato ai pixel. I problemi con l'allineamento dei pixel di solito si manifestano come sfocatura (questo è in particolare true con testo e immagini). Questo è il motivo per cui quando trovo una vista sfocata, per prima cosa controlla se sto impostando la proprietà center. Quando si imposta center, le dimensioni x, y, altezza e larghezza della cornice vengono regolate attorno a quel punto centrale ... con conseguente frequenza di valori frazionari.

Si potrebbe provare a utilizzare CGRectIntegral sul telaio come mostrato:

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

Questo può funzionare, ma se non è così, provare a impostare il frame manualmente, senza utilizzare center proprietà per garantire che nessun valore sono frazionata .

Modifica: Whoops! Non ho notato che l'OP aveva risposto alla sua stessa domanda ... Lascerò questo per ragioni informative comunque.

+1

La maggior parte delle altre risposte (a parte quelle del poster originale) riconosce che si tratta di un problema di allineamento dei pixel, tuttavia +1 per questo poiché è lo scopo più pulito e generale. soluzione – MrCranky

3

IconObj è largo 45 pixel. Sposta il tuo centro IconObj a 265 che ne rende la cornice (242.5, VERTICAL_POINT_ICON - 25 * 0.5, 45, 25). L'immagine sarà sempre sfocata se alcuni dei parametri del frame non sono interi.

Soluzione, calcolare da soli il parametro frame (non utilizzare il centro). E rendilo sempre intero (esegui il cast su NSInteger, usa ceil, floor o round).

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

Ho appena avuto lo stesso problema. Per prima cosa ho pensato che avrei bisogno di occhiali?

Poi ho capito che non è possibile centrare un'immagine (o un'etichetta) quando gli dai un numero dispari. Devi ridimensionare la tua immagine per es. 46 * 46 se vuoi centrarlo e rimanere forte.

Oppure puoi lasciarlo a 45 * 45, ma poi devi decidere se vuoi che l'immagine sia di 1 pixel a destra o 1 pixel a sinistra. (o lasciarlo sfocato).

0

fonte completa per il problema di offset:

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)];