IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Comportement de NtUserDrawIconEx()


Sujet :

Windows

  1. #1
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut Comportement de NtUserDrawIconEx()
    Bonjour,

    Je participe - à temps partiel - à la construction d'un programme qui reproduira un peux l'explorateur windows, en mieux, en utilisant les ressources de la carte vidéo.
    Ceci dit, MÊME les icônes seront dessinés avec une fonction utilisant des algorithmes d'anti-aliasing, genre supersampling - oui c'est lent mais on est encore au stade alpha.

    Pour l'instant, j'essaie de reproduire le comportement de NtUserDrawIconEX() - alias DrawIconEx(). Ensuite, j'implémenterai similaire, maiss utilisant des fonctions extraites de bibliothèques spécialisées.

    Mais... je désire ne pas dépenser trop de temps sur ce travail. Voilà pourquoi je m'essaie ici.

    Mon problème est qu'avec ma fonction actuelle, la qualité est plus que médiocre. Ce n'est rien comparé au travail fait par NtUserDrawIconEx().
    DrawIconEx utilise sûrement d'autres fonctions comme MaskBlt, TransparentBlt, etc. Je me débrouille, mais je ne connais pas bien GDI32.
    J'aimerais qu'on m'aide à raffiner mon code.

    Voici ladite fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    void __stdcall EXPERIMENTAL_DrawIcon(const HDC hDC, const int x, const int y, const HICON hIcon, const HBRUSH hbrBackground) {
    
    	//
    	// Note: On travaille avec des icones 48x48 seulement.
    	//
    
    	ICONINFO icon_info;
    	HDC hdcmem, hdctmp;
    	HBITMAP hbm_mem, hbm_old_1, hbm_old_2;
    
    	hdcmem    = CreateCompatibleDC(hDC);
    	hdctmp    = CreateCompatibleDC(hDC);
    	hbm_mem   = CreateCompatibleBitmap(hDC, 48, 48);
    	hbm_old_1 = SelectObject(hdcmem, hbm_mem);
    
    	GetIconInfo(hIcon, &icon_info);
    
    	if (hbrBackground) {
    		HBRUSH hbrOld;
    
    		hbrOld = SelectObject(hdcmem, hbrBackground);
    		PatBlt(hdcmem, 0x0, 0x0, 48, 48, PATCOPY);
    		SelectObject(hdcmem, hbrOld);
    	}
    
    
    	hbm_old_2 = SelectObject(hdctmp, icon_info.hbmMask);
    	BitBlt(hdcmem, 0x0, 0x0, 48, 48, hdctmp, 0x0, 0x0, SRCAND);
    
    	if (icon_info.hbmColor) {
    		SelectObject(hdctmp, icon_info.hbmColor);
    		BitBlt(hdcmem, 0x0, 0x0, 48, 48, hdctmp, 0x0, 0x0, SRCINVERT);
    	}
    
    	BitBlt(hDC, x, y, 48, 48, hdcmem, 0, 0, SRCCOPY);
    
    	SelectObject(hdctmp, hbm_old_2);
    	SelectObject(hdcmem, hbm_old_1);
    	DeleteObject(hbm_mem);
    	DeleteDC(hdctmp);
    	DeleteDC(hdcmem);
    }

    Voici des icônes dessinés avec NtUserDrawIconEx():



    Voici des icônes dessinés avec la fct expérimentale:




    Comme vous voyez, la différence est très choquante...
    Il y a du noir aux contours...



    Merci,

    Sincèrement,

    Array

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    C'est à cause des histoires d'Alpha Blending, que BitBlt() et cie ne supportent pas.
    Essaie la fonction AlphaBlend().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Je vois.

    Mais, dois-je utiliser AlphaBlend() pour appliquer le masque AND (noir et blanc) ET le masque XOR (couleur)? ou seulement pour l'un des masques?


    Merci bcp :-]

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je ne sais même pas s'il y a un masque AND dans les icônes avec canal Alpha.
    Je pense que tu dois pouvoir te contenter du masque couleur, qui a sans doute une opacité de 100% partout où ça compte.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Citation Envoyé par Médinoc
    Je ne sais même pas s'il y a un masque AND dans les icônes avec canal Alpha.
    C'est ce que j'aimerais essayer, mais la fonction AlphaBlend n'affiche simplement rien. J'ai regardé les valeurs de retour... elle 'return' un code de succès.
    Avec GetLastError(), niet...

    Comment AlphaBlend() fonctionne...?

    EDIT: Ha, après quelques recherches, j'ai découvert que AlphaBlend était une fonction à moitié réussie - M$ -, et qu'il fallait pré-multiplier les valeurs du canal RGB avec celles du canal alpha *sigh*.

  6. #6
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Voilà, j'ai un autre problème.

    Dans ma fonction pour 'loader' un icon, appelée KqnLoadWinIcon, je fais divers appels avec les fonctions de resources:

    1. Appel à FindResource, avec le hModule de la DLL/EXE ayant été chargée avec LoadLibraryEx().
    2. Appel à LoadResource()
    3. Appel à LockResource()

    Rendu à lockresource, j'obtiens un pointeur sur une structure ICONIMAGE, définie comme suit (très similaire à une struct BITMAPINFO) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef struct
    {
    	BITMAPINFOHEADER icHeader;    // DIB header
    	RGBQUAD          icColors[1]; // Color table
    	BYTE             icXOR[1];    // DIB bits for XOR mask
    	BYTE             icAND[1];    // DIB bits for AND mask
    } ICONIMAGE, *LPICONIMAGE;
    
    // Source: http://msdn.microsoft.com/en-us/library/ms997538.aspx
    Rendu là, j'essaie de passer un pointeur sur icColors à une fonction que j'ai fait, intitulée EXPERIMENTAL_DoAlphaPreMultiply(ic_colors, width, height).

    Mais, aussitôt que ma fonction essaie de modifier les données de icColors, bug!!! rien à faire - et ce n'est pas une erreur de mauvais déréférencement, le pointeur *est valide* -, comme si la mémoire était read-only.

    Alors que faire?
    Comment éditer les valeurs de icColors? Dois-je faire un malloc, puis copier TOUTE la structure avec memcpy? Ce serait vrm long... Y-a-t-il un moyen plus facile et/ou rapide?

    Merci,

    Array


    EDIT: En effet, comme cité ici, on ne peut écrire sur la mémoire chargée avec LoadLibraryEx() avec LOAD_LIBRARY_AS_DATAFILE. Sur Vista, il y a une option LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE qui me donnerait des privilèges d'écriture, mais... c'est seulement pour Vista et +, donc je ne peux l'utiliser...
    Y-aurait-t-il un moyen de déverouiller la mémoire par une autre fct?
    Est-ce que je pourrais remplacer la fonction LoadLibraryEx() avec une fonction écrite en C pur, qui ne ferait que copier l'exécutable dans la mémoire avec getchar(), malloc(), etc?

    Merci bcp

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pour faire une fonction qui charge une partie de l'exécutable, il te faudrait étudier le format PE.

    Ne serait-il pas plus simple de faire un LOAD_LIBRARY_AS_DATAFILE et recopier les ressources?
    De plus, ça te permettrait de convertir cette structure, inutilisable telle qu'elle (parce qu'elle contient plusieurs tableaux à taille variable) en quelque chose de plus gérable (structure contenant des pointeurs).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Tu veux dire, faire un LoadLibraryEx, puis copier les resources dans un autre emplacement, puis ensuite faure FreeLibraryEx, et seulement manipuler les resources extraites?

    C'est une bonne idée, mais... mais... comment faire pour recopier une resource? disons que j'ai un groupicon ayant un ID 1524, comment recopier les bytes de la resource seulement? avec memcpy()?
    Et si c'est avec memcpy(), comment savoir la taille en bytes de la resource?

    J'ai vu aussi BeginUpdateResource(). Est-ce qu'une telle function pourrait déverouiller la mémoire?


    Merci!!!

    Array

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ce n'est peut-être pas possible.

    Mais dans tous les cas, j'ai du mal à comprendre le problème qu'il y a à faire un malloc() et un memcpy() après l'appel LockResource()...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Nevermind pour malloc()/memcpy().
    Je croyais juste que tu me disais de recopier la resource dans la mémoire en utilisant malloc() (pour allouer de la place suffisante), suivi de memcpy() pour copier ladite resource.


    Mais bon... pour l'instant, mon problème se limite à faire fonctionner AlphaBlend(). J'ai de la misère à prémultiplier, alors voici une question:

    Ma fonction de drawing [EXPERIMENTAL_DrawIcon()] reçoit en argument un HICON, qui a préalablement été créé par LoadImage().
    J'utilise donc GetIconInfo() pour retrouver le HBITMAP (un DDB) du masque couleur de l'icône (membre hbmColor d'une structure ICONINFO).
    Comment prémultiplier les valeurs RGB de iconInfo.hbmColor avec son canal alpha?
    Dois-je utiliser GetDIBits, GetDIBColorTable()?

    Je suis allé voir sur ReactOS [le OS visant à faire un Windows NT open-source légalement], et ils utilisent GetBitmapBits().
    MAIS, GetBitmapBits() est 'deprecated'...


    Merci!

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je te conseillerais GetObject() pour connaître la résolution du bitmap (et ne faire de AlphaBlend que si c'est un RGBA), puis GetDIBits() vers un buffer à toi.

    GetDIBColorTable() ne te servira pas ici, vu que les bitmaps 32 bits RGBA n'ont pas de palette de couleurs.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Ha! Merci, grâce à ça je peux enfin programmer à la place de ne faire que des recherches.

    Voilà que durant le dév, je suis tombé sur ce texte de msdn.
    Je voudrais qu'on m'explique pourquoi? pourquoi cette formule, ici?

    Citation Envoyé par msdn
    # Appelez la fonction GetDIBits() avec le contexte de périphérique voulu (DC), un pointeur vers le bloc de mémoire que lpBitsInfo et NULL en tant que paramètre lpBits. Cela force le pilote de périphérique pour renseigner le champ biSizeImage de la structure BITMAPINFOHEADER (ce champ doit avoir été initialisé à 0 dans l'étape 1). Le champ biSizeImage indique la quantité de mémoire requise pour stocker les bits qui composent l'image de la DIB (en octets). Si ce champ reste 0 après un appel GetDIBits() , l'application doit calculer biSizeImage à l'aide de la formule suivante :

    ((((biWidth * biBitCount) + 31) & ~31) >> 3) * biHeight

    cette formule est nécessaire car chaque ligne d'analyse de l'image est aligné sur une limite DWORD.
    Src: http://support.microsoft.com/kb/80080

    Je comprends bien entendu les opérateurs et tout, mais... pourquoi additionner 31?

    J"ai également vu une autre variante:
    bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight;

    Si quun pouvait m'expliquer 'en quoi' cette formule aligne sur un int, ce serait bien.

    Merci'''

    Array

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    On ajoute 31 avant de mettre les bits à zéro, pour arrondir à 32 supérieurs. Si on n'ajoutait pas 31 avant, on arrondirait à 32 inférieurs.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    On ajoute 31 avant de mettre les bits à zéro, pour arrondir à 32 supérieurs. Si on n'ajoutait pas 31 avant, on arrondirait à 32 inférieurs.
    C'est en lisant cette réponse que j'ai réalisé la stupidité de ma question. Si on n'additionnait pas 31, il pourrait dans certains cas manquer un DWORD, ce qui créerait une erreur...


    Je me demande aussi :
    Appelez la fonction GetDIBits() avec le contexte de périphérique voulu (DC), un pointeur vers le bloc de mémoire que lpBitsInfo et NULL en tant que paramètre lpBits. Cela force le pilote de périphérique pour renseigner le champ biSizeImage de la structure BITMAPINFOHEADER (ce champ doit avoir été initialisé à 0 dans l'étape 1). Le champ biSizeImage indique la quantité de mémoire requise pour stocker les bits qui composent l'image de la DIB (en octets). Si ce champ reste 0 après un appel GetDIBits() , l'application doit calculer biSizeImage à l'aide de la formule suivante :
    [...]
    Pourquoi absolument appeler GetDIBits()? Ne serait-il pas plus simple, et également plus rapide pour la machine de faire directement le calcul?


    Merci :-]


    Sincèrement,

    Array

  15. #15
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    S.v.p. une réponse!
    Même si vous ne le savez pas, au moins ne serais-ce qu'une opinion serait bienvenue.

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    J'ai du mal à comprendre la question. En fait, j'ai tendance à calculer moi-même: Je ne savais même pas qu'on pouvait appeler GetDIBits() dans un autre but que récupérer le contenu de l'image...

    Note aussi que GetDIBits() est capable de convertir une image depuis sont format d'origine vers celui que tu spécifies dans ta structure BITMAPINFO. Et contrairement à Paint, ça ne te pourrit pas trop les couleurs quand tu convertis de 24 bits à 8 bits... (enfin, c'est sous XP que j'avais testé. Peut-être que c'est aussi pourrir sous 9x).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Désolé, je n'ai peut-être pas été clair.

    En bref, l'objectif de ce topic a été accompli : Ma fonction affiche parfaitement les icônes. De plus, elle est plus rapide de 300 à 450 ms!

    Cependant, je dois, dans le processus, créer un DIB à partir d'un DDB.
    Je me suis renseigné auprès de Microsoft.

    Eux, ils recommandent de faire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    - Appeler GetDIBits avec lpvBits nul, pour que le 'device driver' essaie lui-même de calculer la champ .biSizeImage (si le .biSizeImage du bitmapinfo passé est à 0).
    
    - Si le 'device driver' n'a pas rempli .biSizeImage, utiliser la formule.
    Moi, j'essaie d'optimizer un max mes fonctions, et je me demande si appeler GetDIBits() est plus lent que faire directement le calcul, sans jamais appeler GetDIBits().
    En plus, il n'est pas garanti que le 'device driver' va calculer lui-même le .biSizeImage - même s'il le fait la plupart du temps. On doit donc ajouter un 'if' pour être certain que le 'device driver' a fait son travail.

    Alors, je me demandais ce que tu crois être le plus rapide.
    En fais, pour que l'alternative utilisant GetDIBits() soit plus rapide, il faudrait que .biSizeImage soit calculé directement dans le GPU... Je ne sais même pas si c'est le cas.

    Pour l'instant ça ne fait pas de différence entre les deux méthodes, mais si ma fonction devait, dans des conditions bien sûr extrêmes, dessiner plusieurs centaines d'icônes, ça deviendrait significatif.


    Note aussi que GetDIBits() est capable de convertir une image depuis sont format d'origine vers celui que tu spécifies dans ta structure BITMAPINFO. Et contrairement à Paint, ça ne te pourrit pas trop les couleurs quand tu convertis de 24 bits à 8 bits... (enfin, c'est sous XP que j'avais testé. Peut-être que c'est aussi pourrir sous 9x).
    o_O Je ne savais pas, ça me sauveras certainement du temps quand j'adapterai ma fonction pour convertir aussi des image vers d'autres formats - NT4 et + seulement, on supportera pas Win9x, du moins pour l'instant.

Discussions similaires

  1. open avec comport
    Par Goldocrack dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/04/2009, 08h12
  2. [HttpClient] comportement bizarre, saute des catch()...
    Par iubito dans le forum Développement Web en Java
    Réponses: 4
    Dernier message: 04/02/2004, 15h25
  3. [Sybase] Comportement bizarre d'une table
    Par sdozias dans le forum Sybase
    Réponses: 4
    Dernier message: 03/02/2004, 10h39
  4. [Free Pascal] Comportement de Exec
    Par néo333 dans le forum Free Pascal
    Réponses: 3
    Dernier message: 01/11/2003, 17h46
  5. Réponses: 2
    Dernier message: 22/09/2003, 11h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo