Disegnare un'immagine in un NSView
-
12-09-2019 - |
Domanda
Ho un semplice programma Obj C che, al momento, permette di caricare un'immagine, disegna in su, e teoricamente dovrebbe lasciare che si esegue lo zoom e ruotare. Sto utilizzando NSAffineTranslations.
Voglio che l'immagine da bloccare in alto a sinistra (in contrasto con lo standard / PDF PS di basso a sinistra), quindi sto usando isFlipped, e chiamando [afTrans scaleXBy: 1.0 YBY: -1.0];
Il problema è che per qualche motivo, dopo la prima volta che il mio drawRect si chiama, la trasformazione non avviene.
Quando carico un'immagine, si tratta, e sembra corretto. Se cambio la dimensione della finestra (che chiama drawRect), l'immagine disegna, ma è capovolta e invertita. Ciò significa che la trasformazione non ha preso effetto. Non vedo alcuna differenza in nessuno dei dati del 2 ° tempo attraverso.
Questa è una versione ridotta del codice:
- (void)drawRect:(NSRect)rect
{
// Drawing code here.
// NSLog(@"window type: %d", [[self window] backingType]);
NSAffineTransform *afTrans = [[NSAffineTransform alloc] init];
NSGraphicsContext *context = [NSGraphicsContext currentContext];
NSSize sz;
NSRect windowFrame = [[self window] frame];
NSRect cv =[[[self window] contentView] frame];
float deltaX, deltaY;
NSSize superSize = [[self superview] frame].size;
float height, width, sHeight, sWidth;
NSRect imageRect;
sz = [ image size];
imageRect.size = sz;
imageRect.origin = NSZeroPoint;
height = sz.height ;
width = sz.width ;
// sHeight and sWidth are the hieght and with of the super-view. ie,
// the size of the whole window view including the space for the
// scroll bars, etc, but not including the panel or the borders,
sHeight = superSize.height;
sWidth = superSize.width;
[context saveGraphicsState];
deltaX = 0;
deltaY = 0;
deltaY += height; // account for flipping
[afTrans translateXBy:deltaX yBy:deltaY];
[afTrans scaleXBy:1.0 yBy:-1.0];
[afTrans concat];
NSRect drawingRect = imageRect;
NSRect frame = imageRect;
[self setFrame:frame];
[image drawInRect:drawingRect
fromRect:imageRect
operation:NSCompositeSourceOver
fraction:1];
[afTrans release];
[context restoreGraphicsState];
}
ETA: ecco qualche codice più che potrebbero essere rilevanti
.-(void )setImage:( NSImage * )newImage
{
[newImage retain];
[image release];
rotation = 0;
zoom = 1.0;
image = newImage;
NSSize imageSize = [newImage size];
NSRect tFrame = [self frame];
tFrame = [[self window] frame];
tFrame.size.width = MAX(tFrame.size.width, imageSize.width);
tFrame.size.height = MAX(tFrame.size.height, imageSize.height);
[self setFrame:tFrame];
[self setNeedsDisplay:YES];
}
Soluzione
Non sono sicuro di quello che si sta cercando di raggiungere, ma se si desidera disegnare solo un'immagine in un NSView e tenerlo in alto a sinistra, si può fare qualcosa di un po 'più semplice, nella sottoclasse NSView:
- (BOOL)isFlipped
{
return YES;
}
- (void)setImage:(NSImage *)newImage
{
[newImage retain];
[image release];
image = newImage;
[image setFlipped:YES];
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)rect
{
[image drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
// Or stretch image to fill view
//[image drawInRect:[self bounds] fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
}
Sono stato anche in grado di ottenere risultati simili con il codice per sbarazzarsi delle chiamate [self setFrame:...];
in drawRect e setImage metodi.
Altri suggerimenti
Supponendo che non stai escludendo il codice che cambia roba, attenzione se si sta disegnando l'immagine altrove. elementi della barra degli strumenti, tabelle e così via potrebbero modificare la proprietà -flipped dell'immagine, inducendolo a disegnare in modo non corretto.
Prova questo intorno alla linea di disegno immagine:
BOOL wasFlipped = [image isFlipped];
[image setFlipped:[self isFlipped]];
[image drawInRect:drawingRect
fromRect:imageRect
operation:NSCompositeSourceOver
fraction:1];
[image setFlipped:wasFlipped];
Vedere se questo aiuta. Se non , guardare altrove nel codice per qualcosa che cambia proprietà capovolto dell'immagine e non rimetterlo.