NSWorkspace sharedWorkspace iconeForFile - Ultra couteux.... Y a mieux ?

LeChatNoirLeChatNoir Membre, Modérateur
07:44 modifié dans API AppKit #1
Slt,
Tjs le nez dans mes optimisations, je constate que récupérer l'icone d'un fichier est couteux et limité.
* Couteux : à  chaque fichier exploré, je fais un [[NSWorkspace sharedWorkspace] iconForFile:monfichier]. Ca rallonge sacrément mon listing => y a plus performant ?
* limité : ça ramène forcément l'icone en 32*32 donc obligé de resizer l'icone en 16*16 parce que je veux l'icone en 16*16. Y a mieux ?

Merci de vos lumières !

Réponses

  • 07:44 modifié #2
    Pour ce genre de cas (c'est pour ton FTP je présume?), je pense que le mieux est d'utiliser iconForFileType: au lieu de iconForFile: et de garder les icones en 16*16 dans un dico qui te sert de cache (en utilisant l'extension comme clé) - note que tu peux aussi faire un cache en gardant un icone par fichier, mais ce sera bien plus lourd. De cette manière, quand tu as besoin d'une image, tu vas la chercher dans le cache plutot que via nsworkspace.
  • AliGatorAliGator Membre, Modérateur
    07:44 modifié #3
    Il me semble que pas mal de logiciels de client FTP ont une option dans les préférences genre "afficher l'icône personalisée", décochée par défaut.
    Autrement dit par défaut il prenne le iconForFileType, selon l'extension/type... et ils ne prennent le iconForFile (icône perso) que si tu le demandes.

    Ce qui irait dans le sens de "oui c'est normal que ce soit long" et surtout "non y'a pas plus rapide", et du coup je serais toi je chercherai pas midi à  14h pour essayer d'optimiser cette récupération d'icône ;)

    Bon ok c'est peut-être un peu rapide comme conclusion, mais je suppose que si les clients FTP proposent ce genre d'option c'est que justement c'est long de récupérer l'icône personalisée pour chaque fichier... et que eux non plus n'ont pas trouvé plus rapide :P
  • 07:44 modifié #4
    Salut,

    Moi pour un affiché l'icône d'un download (en fonction de l'extension) j'utilise :
    <br />[[NSWorkspace sharedWorkspace] iconForFileType:[myString pathExtension]];
    

    Et tu peux récupérer l'icone en différentes tailles (128*128 maxi, 32*32 par défaut).

    @+
    Louka
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:44 modifié #5
    Oui c'est pour mon client FTP (ben désolé, j'avance pas vite !).
    Bon ben je suis déçu :-(
    Merci à  tous de vos conseils, je vais voir ce que je fais...

    a+
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:44 modifié #6
    Quoi que...
    A y réfléchir, le finder le fait bien lui ?!
    Il affiche bien les fichiers rapidements avec les icones associés.

    Donc il doit bien y avoir moyen non ?
  • 07:44 modifié #7
    Le Finder utilise un système de cache.
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:44 modifié #8
    Et ben aller, je vais m'y coller alors.
    Cache+thread, je devrais m'en tirer.

    Par contre, ca va être long :-( Mon client FTP n'est pas prêt de voir le jour !

    J'ai même pas encore touché à  un cheveux du protocole FTP !!!
  • Eddy58Eddy58 Membre
    07:44 modifié #9
    Le mieux je pense est de passer par les Icon Services, qui te permettent d'accéder au système de cache du système. Bon c'est vrai c'est juste une piste j'ai pas fait le plus difficile là ...:P
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:44 modifié #10
    Great Idea !
    Merci !
    Le gars qui a fait UKDirectoryEnumerator (équivament à  DirectoryEnumerator Cocoa mais en Carbon donc sensé être plus performant) m'a filé du code sur lequel il bosse et qui utilise les icon services.

    Je vais donc gratter dans ce sens et tenté de mettre une sorte de cache.

    Et je vais arrêter là  l'optimisation. Je vais tenter de me concentrer enfin sur le coeur du client FTP : le protocol FTP  :P

    a+
  • mars 2006 modifié #11
    - (NSImage*)getIconFromFileAtPath:(NSString*)path<br />{<br />	NSImage *image=nil;<br />	if (FSPathMakeRef((UInt8*)[path fileSystemRepresentation],&amp;theRefIcon,NULL)==noErr)<br />	{<br />		if (FSGetCatalogInfo(&amp;theRefIcon,kFSCatInfoNone,NULL,NULL,&amp;theSpecIcon,NULL)==noErr)<br />		{<br />			if (GetIconRefFromFile(&amp;theSpecIcon,&amp;theIconRefIcon,&amp;theLabelIcon)==noErr)<br />			{<br />				RGBColor *cLabel=NULL;<br />				if (theLabelIcon&gt;0)<br />				{<br />					//NSLog(@&quot;theLabel %d&quot;,theLabel);<br />					cLabel=&amp;finderColorLabels[theLabelIcon-1];<br />				}<br />				image=[[NSImage alloc] initWithSize:nsSizeIcon];<br />				[image lockFocus];<br />				PlotIconRefInContext((CGContextRef)[[NSGraphicsContext currentContext] graphicsPort],<br />			&amp;cgRectIcon,<br />			kAlignNone,<br />			kTransformNone,<br />			cLabel,<br />			kPlotIconRefNormalFlags,<br />			theIconRefIcon<br />);<br />				[image unlockFocus];<br />				ReleaseIconRef(theIconRefIcon);<br />			}<br />			<br />		}<br /><br />	}<br />	return image;<br />}
    


    Moi je suis le gas qui fait piquantmenu
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:44 modifié #12
    Slt et merci de ton aide "legarskifaitPiquantMenu" !  ::)
    Bon moi je suis le gars qui est une bille en Carbon alors j'ai fait un  :)beta: copier/coller de ton code et bien sur, le compilo m'a gueulé dessus.

    Donc j'ai vaguement chercher et voilà  ce que j'ai tenté :
    <br />&nbsp; &nbsp;  NSImage *image=nil;<br />	NSString * path=MonPathAMoi;<br />	FSRef theRefIcon;<br />	FSSpec theSpecIcon;<br />	SInt16 theLabelIcon;<br />	IconRef theIconRefIcon;<br />	if (FSPathMakeRef((UInt8*)[path fileSystemRepresentation],&amp;theRefIcon,NULL)==noErr)<br />	{<br />		if (FSGetCatalogInfo(&amp;theRefIcon,kFSCatInfoNone,NULL,NULL,&amp;theSpecIcon,NULL)==noErr)<br />		{<br />			if (GetIconRefFromFile(&amp;theSpecIcon,&amp;theIconRefIcon,&amp;theLabelIcon)==noErr)<br />			{<br />				RGBColor *cLabel=NULL;<br />				if (theLabelIcon&gt;0)<br />				{<br />					//NSLog(@&quot;theLabel %d&quot;,theLabel);<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  //cLabel=&amp;finderColorLabels[theLabelIcon-1]; <br />//				??Rien compris ??<br />				}<br />				image=[[NSImage alloc] initWithSize:NSMakeSize(16,16)];<br />				[image lockFocus];<br />				 RGBColor&nbsp; &nbsp; &nbsp; &nbsp; labelColor = { 0, 0, 0 };<br />				 NSRect * rect; ??ca sert a quoi ?<br />				PlotIconRefInContext((CGContextRef)[[NSGraphicsContext currentContext] graphicsPort],<br />									 (const CGRect*) &amp;rect,<br />									 kAlignNone,<br />									 kTransformNone,<br />									 &amp;labelColor,<br />									 kPlotIconRefNormalFlags,<br />									 theIconRefIcon<br />									 );<br />				[image unlockFocus];<br />				ReleaseIconRef(theIconRefIcon);<br />			}<br />			<br />		}<br />		<br />	}<br />	[self setIcon:image];<br />
    


    Ca compile et ca marche sur les premiers nodes de la racine, à  savoir /Applications, /Network etc mais paf, le PlotMachinChose se vautre sur le node /sw.
    Pourquoi, j'en sais rien...

    Un autre ch'tit coup de main  :-* ?
  • mars 2006 modifié #13
    Dans un premier temps tu peux supprimer  la gestion des familles qui n'est pas fiable (certains labels sont inversés, j'ai loupé un truc peut être).
    <br />RGBColor *cLabel=NULL;<br />				if (theLabelIcon&gt;0)<br />				{<br />				//NSLog(@&quot;theLabel %d&quot;,theLabel);<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //cLabel=&amp;finderColorLabels[theLabelIcon-1]; <br />				}<br />
    


    Et remplacer &labelColor et &theLabelIcon par NULL.
    Note que l'image n'est pas "releasée" si tu ne le fais pas.
    Pour le rect je sais plus mais à  mon avis si il y est ce que ça doit plus marcher sans.

    Mon exemple n'est pas forcément parfait alors n'hésites pas à  l'améliorer (et le signaler)

    Chez moi ça marche sur tous les fichiers "normaux" ? C'est quoi /sw ?
  • LeChatNoirLeChatNoir Membre, Modérateur
    07:44 modifié #14
    Ok merci !
    Je testerai ça plus tard (je peux pas là ...).
    J'avais pas pigé que c'était pour les étiquettes !

    /sw, c'est tout ce qui est packages fink je crois. C'est un dossier plutot normal et sur lequel il n'y a a priori pas de pb de droits.

    Je te tiens au courant plus tard.
    a+
Connectez-vous ou Inscrivez-vous pour répondre.