[RESOLU] CGImage à partir d'un pasteboard
Philippe49
Membre
J'ai de nouveau un problème avec les CGImage :
Résultat
Tout a l'air de fonctionner jusqu'à la création de la CGImage
Apple PICT pasteboard type
Length of data : 334364
status of imageSourceRef : 0 (kCGImageStatusComplete=0)
2008-01-05 09:59:35.655 Drag_Drop01[493:10b] {
FileSize = 334364;
}
imageRef not created
Le passage par CGImageSource est recommandé par Apple et il a fonctionné jusqu'à maintenant. (voir par exemple le dragging destination)
On peut faire ainsi ;
// NSImage * image=[[NSImage alloc] initWithPasteboard:pb] ;
// NSBitmapImageRep * bitmapImageRep=(id)[image bestRepresentationForDevice:nil];
// CGImageRef imageRef=[bitmapImageRep CGImage] ;
// rootLayer.contents = (id)imageRef;
// [image release];
// CGImageRelease(imageRef);
mais le [image release] crée un problème mémoire (la CGImage se sert sans doute de la NSImage comme imageSource (dataProvider dans l'ancien modèle))
-(IBAction)paste:(id) sender<br />{<br /> // On récupère le general pasteboard<br /> NSPasteboard *pb = [NSPasteboard generalPasteboard];<br /> NSString * type=[pb availableTypeFromArray:[NSImage imageUnfilteredPasteboardTypes]];<br /><br /> <br /> if(type==nil) { <br /> return;<br /> } else {<br /> fprintf(stderr,"%s\n", [type UTF8String]);<br /> } <br /><br /> // on récupère le data<br /> NSData * data=[pb dataForType:type];<br /> CFDataRef dataRef=(CFDataRef) data;<br /> if(dataRef){<br /> fprintf(stderr,"Length of data : %d\n",CFDataGetLength(dataRef));<br /> } else {<br /> fprintf(stderr,"dataRef not created\n");<br /> return;<br /> }<br /><br /><br /> // on en fait une image source<br /> CGImageSourceRef imageSourceRef=CGImageSourceCreateWithData(dataRef, NULL);<br /> if(imageSourceRef){<br /> fprintf(stderr,"status of imageSourceRef : %d (kCGImageStatusComplete=0) \n",CGImageSourceGetStatus(imageSourceRef));<br /> NSLog(@"%@",(NSDictionary*) CGImageSourceCopyProperties(imageSourceRef,NULL));<br /> }<br /> <br /> // on en fait une image<br /> CGImageRef imageRef=CGImageSourceCreateImageAtIndex(imageSourceRef, 0, NULL); <br /> if(imageRef){<br /> fprintf(stderr,"%d\n",CGImageGetWidth(imageRef)); <br /> } else { <br /> fprintf(stderr,"imageRef not created");<br /> return;<br /> }<br /> <br /> // utilisation<br /> CFRelease(imageSourceRef);<br /> rootLayer.contents = (id) imageRef;<br /> CGImageRelease(imageRef);<br />}
Résultat
Tout a l'air de fonctionner jusqu'à la création de la CGImage
Apple PICT pasteboard type
Length of data : 334364
status of imageSourceRef : 0 (kCGImageStatusComplete=0)
2008-01-05 09:59:35.655 Drag_Drop01[493:10b] {
FileSize = 334364;
}
imageRef not created
Le passage par CGImageSource est recommandé par Apple et il a fonctionné jusqu'à maintenant. (voir par exemple le dragging destination)
On peut faire ainsi ;
// NSImage * image=[[NSImage alloc] initWithPasteboard:pb] ;
// NSBitmapImageRep * bitmapImageRep=(id)[image bestRepresentationForDevice:nil];
// CGImageRef imageRef=[bitmapImageRep CGImage] ;
// rootLayer.contents = (id)imageRef;
// [image release];
// CGImageRelease(imageRef);
mais le [image release] crée un problème mémoire (la CGImage se sert sans doute de la NSImage comme imageSource (dataProvider dans l'ancien modèle))
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Quand tu dis "recommandé par Apple", est-ce que tu peux citer tes sources ?
Pourquoi CGImageRelease(imageRef); ?
Tu ne dois faire un release que sur un object que tu as créé or ici, imageRef vient de [bitmapImageRep CGImage] qui est autoreleasé.
C'est le résultat d'un "copy" dans "aperçu"
Ah. C'est une piste. Pour moi, NSImage ne devrait pas être plus élaboré que CGImage qui est de plus bas niveau ?
Dans la doc CGDataProvider reference (overview), on lit
If your application runs in Mac OS X v10.4 or later, you should use CGImageSource objects rather than data providers. See CGImageSource Reference.
Autant pour moi, un copier-coller mécanique : effectivement, ici [bitmapImageRep CGImage]Â renvoie en autorelease.
Cela marche en le retirant, sans fuite mémoire.
Je vais le prendre ainsi, mais je suis déçu que cela ne marche pas avec le CGImageSource : Je m'étais inspiré d'un exemple distribué par Apple (GeekGameBoard).
Lors d'un copier-coller sur une grande portion d'image (valeur de 2-3 Mo qui dans le moniteur d'activités passe à 20 Mo, mémoire réelle) , cela plante, alors que mon code via le data lui résiste bien.
Résolu : il suffit de boucler sur tous les types proposés par le general pasteboard
Le general pasteboard propose 4 ou 5 types, le premier étant "public.tiff" et cela passe en l'état.
ceci dit c'est pas beau je te l'accorde ... (de guitare)
Qui retourne le premier type de NSArray qu'il trouve dans tous les types proposés par le pasteboard ?
Il te suffit donc de faire un NSArray avec un seul élément qui sera la NSString de ton type et si le retour de la fonction n'est pas nul c'est qu'il a été trouvé. Ensuite tu utilises la méthode avec la même NSString que t'as passé à ton NSArray pour récupérer les bonnes données.
remontes un peu dans le post
Le code utilisé est ici.
à moins que CGimage ne fournisse les types qu'il est susceptible de gérer ?
CGImageSourceCopyTypeIdentifiers
Returns an array of uniform type identifiers (UTIs) that are supported for image sources.
CFArrayRef CGImageSourceCopyTypeIdentifiers (
  void
);
Return Value
Returns an array of the UTIs that are supported for image sources.
NSLog(@%@",(NSArray*) CGImageSourceCopyTypeIdentifiers());
2008-01-05 20:34:19.993 Drag_Drop01[2318:10b] (
  "public.png",
  "public.jpeg",
  "com.compuserve.gif",
  "public.jpeg-2000",
  "com.nikon.raw-image",
  "com.leafamerica.raw-image",
  "com.hasselblad.fff-raw-image",
  "com.hasselblad.3fr-raw-image",
  "com.pentax.raw-image",
  "com.sony.arw-raw-image",
  "com.adobe.raw-image",
  "public.tiff",
  "com.apple.icns",
  "com.canon.crw-raw-image",
  "com.canon.cr2-raw-image",
  "com.canon.tif-raw-image",
  "com.sony.raw-image",
  "com.olympus.raw-image",
  "com.konicaminolta.raw-image",
  "com.panasonic.raw-image",
  "com.fuji.raw-image",
  "com.adobe.photoshop-image",
  "com.adobe.pdf",
  "com.adobe.illustrator.ai-image",
  "com.microsoft.ico",
  "com.microsoft.bmp",
  "public.xbitmap-image",
  "com.microsoft.cur",
  "com.apple.pict",
  "com.truevision.tga-image",
  "com.sgi.sgi-image",
  "com.apple.quicktime-image",
  "com.kodak.flashpix-image",
  "com.apple.macpaint-image",
  "com.ilm.openexr-image",
  "public.radiance"
)
:kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: :kicking: