2010-03-22 8 views
1

J'essaie d'utiliser la fonction de sélection et de copie de IKImageView. Si tout ce que vous voulez faire est d'avoir une application avec une image, sélectionnez une partie et copiez-la dans le presse-papiers, c'est facile. Vous définissez le choix du menu de copie sur la copie du premier répondant: méthode (id) et tout fonctionne magiquement.Un autre IKImageView Question: copier une région

Cependant, si vous voulez quelque chose de plus compliqué, comme vous voulez copier dans le cadre d'une autre opération, je n'arrive pas à trouver la méthode pour le faire.

IKImageView ne semble pas avoir de méthode de copie, il ne semble pas avoir une méthode qui vous dira même le rectangle sélectionné!

Je suis passé par le livre de Hillegass, donc je comprends comment fonctionne le presse-papiers, tout simplement pas comment la partie de l'image de la vue ...

Maintenant, je commence à penser que J'ai fait une erreur en basant mon projet sur IKImageView, mais c'est sur quoi Preview est construit (ou j'ai lu), donc j'ai pensé que ça devait être stable ... et de toute façon, maintenant c'est trop tard, je suis trop en profondeur pour recommencer ...

Donc, en plus de ne pas utiliser IKImageView, des suggestions sur la façon de copier manuellement la région sélectionnée dans le presse-papiers?

EDIT En fait, je l'ai trouvé la copie (id) méthode, mais quand je l'appelle, je reçois

<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaPremultipliedLast; 2624 bytes/row. 

Ce qui, évidemment, ne se produit pas lorsque je fais une copie normale par la de première répondeur ... Je comprends le message d'erreur, mais je ne suis pas sûr d'où il tire ces paramètres ...

Y at-il un moyen de suivre cela et de voir comment cela se passe? Un débogueur ne sera pas utile pour des raisons évidentes, ainsi que le fait que je fais cela dans Mozilla, si un débogueur est pas une option quand même ...

EDIT 2 Il me semble que la copy: (id) méthode que je trouve peut-être copier la vue plutôt que de copier un morceau de l'image dans le presse-papiers, ce qui est ce dont j'ai besoin. La raison pour laquelle je pensais que c'était la copie du presse-papiers est que dans un autre projet, où je copie depuis IKImageView dans le presse-papiers directement à partir du menu d'édition, il envoie juste une copie: (id) au firstResponder, mais Je ne suis pas vraiment sûr de ce que l'firstresponder fait avec elle ...

EDIT 3 il semble que l'erreur CGBitmapContextCreate vient [imageView image] qui, assez curieusement, IS une méthode documentée.

Il est possible que cela se produise parce que je mets l'image dedans avec une méthode setImage: (id), en passant un NSImage * ... Y at-il une autre façon plus intelligente d'obtenir un NSImage dans un IKImageView?

+0

Vous pouvez certainement les plug-ins de débogage dans une application externe tel que Mozilla/Firefox. Créez simplement un exécutable personnalisé dans votre projet Xcode et pointez-le sur l'application que vous souhaitez déboguer. J'ai très bien réussi avec Safari, Dreamweaver, Adobe GoLive et d'autres. –

+0

"Il me vient à l'esprit que la méthode' copy: (id) 'que j'ai trouvée est peut-être en train de copier la vue plutôt que de copier une partie de l'image dans le presse-papiers ..." Non.), qui renvoie une copie de l'objet et ne fonctionne pas sur les vues. 'copy:' (un argument) 'est une action qui indique au récepteur (la vue) de copier sa sélection dans le presse-papiers. –

Répondre

0

La méthode -copy: dans IKImageView fait ce que fait toute autre méthode -copy:: elle copie la sélection en cours dans le presse-papiers. Il est cependant implémenté en tant que méthode privée dans IKImageView pour une raison quelconque.

Vous pouvez simplement appeler directement:

[imageView copy:nil]; 

Cette copie tout ce qui est sélectionné dans le presse papier.

Je ne pense pas qu'il existe un moyen d'accéder directement au contenu de l'image de la sélection en IKImageView en utilisant des méthodes publiques, c'est un bon candidat pour un rapport de bug/demande de fonctionnalité.

Vous pouvez toutefois utiliser la méthode privée -selectionRect pour obtenir un CGRect de la sélection et l'utiliser pour extraire la partie sélectionnée de l'image:

//stop the compiler from complaining when we call a private method 
@interface IKImageView (CompilerSTFU) 
- (CGRect)selectionRect 
@end 

@implementation YourController 
//imageView is an IBOutlet connected to your IKImageView 
- (NSImage*)selectedImage 
{ 
    //get the current selection 
    CGRect selection = [imageView selectionRect]; 

    //get the portion of the image that the selection defines 
    CGImageRef selectedImage = CGImageCreateWithImageInRect([imageView image],(CGRect)selection); 

    //convert it to an NSBitmapImageRep 
    NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCGImage:selectedImage] autorelease]; 
    CGImageRelease(selectedImage); 

    //create an image from the bitmap data 
    NSImage* image = [[[NSImage alloc] initWithData:[bitmap TIFFRepresentation]] autorelease]; 

    //in 10.6 you can skip converting to an NSBitmapImageRep by doing this: 
    //NSImage* image = [[NSImage alloc] initWithCGImage:selectedImage size:NSZeroSize];  
    return image; 
} 
@end 
+0

N'oubliez pas de tester si 'imageView' répond à' selectionRect'. Comme il s'agit d'une méthode privée, Apple peut renommer, modifier ou supprimer cette méthode à tout moment, en brisant votre code s'il envoie ce message sans condition. –

+0

Lorsque j'essaie la [copie imageView: nil] je reçois : CGBitmapContextCreate: combinaison de paramètres non prise en charge: 8 bits/composant entiers; 16 bits/pixel; Espace colorimétrique à 1 composant; kCGImageAlphaPremultipliedLast; 2624 octets/ligne. –

+0

Et j'obtiens la même erreur quand j'essaie ta méthode ... –

0

Ok, donc la copie: néant échoue, et [ImageView image] échoue, mais il s'avère que j'ai une autre copie du NSImage à partir de quand je l'ai ajouté dans la vue en premier lieu, donc je pourrais le faire. De plus, CGImageCreateWithImageInRect s'attend à ce qu'un CGImageRef ne soit pas un NSImage *, j'ai donc dû faire quelques conversions. De plus, pour une raison ou une autre, le rectangle de sélection est retourné, que ce soit en bas, et que l'image soit en haut, ou inversement, donc j'ai dû la retourner.

Et pour une raison quelconque, le compilateur soudainement commencé à se plaindre que NSRect n'est pas le même type que CGRect (ce qui implique qu'il est soudainement allé de 32 à 64 bits ou quelque chose ... ne sais pas pourquoi ...)

Quoi qu'il en soit

, voici ma copie de SelectedImage:

- (NSImage*)selectedImage 
{ 
    //get the current selection 
    CGRect selection = flipCGRect(imageView, [imageView selectionRect]); 

    //get the portion of the image that the selection defines 
    struct CGImage * full = [[doc currentImage] CGImageForProposedRect: NULL context: NULL hints: NULL]; 

    CGImageRef selectedImage = CGImageCreateWithImageInRect(full, selection); 


    //convert it to an NSBitmapImageRep 
    NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCGImage:selectedImage] autorelease]; 
    CGImageRelease(selectedImage); 

//  //create an image from the bitmap data 
    NSImage* image = [[[NSImage alloc] initWithData:[bitmap TIFFRepresentation]] autorelease]; 

//  //in 10.6 you can skip converting to an NSBitmapImageRep by doing this: 
    //NSImage* image = [[NSImage alloc] initWithCGImage:selectedImage size:NSZeroSize];  
    return image; 

} 

j'ai écrit flipCGRect et [doc currentImage] retourne un NSImage * ...