Adapter couleur de fond NSView en fonction du contenu

J'affiche mon style de trait courant dans une NSView avec son épaisseur, son pointillé et sa couleur sur un fond blanc.


C'est chouette mais absolument horrible lorsque la couleur est claire (jaune, gris pale etc).


Existe t'il une solution pour passer le fond en noir ou gris sombre lorsque la couleur du trait est claire ?


 

Ceci est lisible

Réponses



  • J'affiche mon style de trait courant dans une NSView avec son épaisseur, son pointillé et sa couleur sur un fond blanc.


    C'est chouette mais absolument horrible lorsque la couleur est claire (jaune, gris pale etc).


    Existe t'il une solution pour passer le fond en noir ou gris sombre lorsque la couleur du trait est claire ?


     

    Ceci est lisible attachicon.gifCapture d'écran 2014-01-03 à  14.51.37.png


    Mais pas ceci attachicon.gifCapture d'écran 2014-01-03 à  14.52.05.png




     


    Matt Gemmell a fait un exemple pour les labels, c'est le même principe


     


    voir http://mattgemmell.com/nscolorcontrastinglabelextensions/

  • AliGatorAliGator Membre, Modérateur
    Bizarre sa solution à  Matt : pourquoi convertir la NSColor dans l'espace RGB (Red/Green/Blue) pour finalement calculer la composante grise en faisant la moyenne des 3 couleurs, plutôt que de directement convertir la NSColor dans l'espace GrayScale (niveaux de gris) directement et laisser ainsi Cocoa faire le calcul pour toi ?

    D'autant que le niveau de gris d'une couleur RGB si on veut être strict n'est pas rigoureusement égal à  la moyenne (R+G+B)/3 dû au facteur psycho-visuel de l'oeil humain qui ne perçoit pas le Rouge, le Vert et le Bleu avec la même intensité/luminosité...
  • mpergandmpergand Membre
    janvier 2014 modifié #4

    Voici la méthode que j'utilise pour convertir une couleur en niveaux de gris en fonction de sa luminance :



    -(NSColor*) grayScale
    {
    NSColor* color=[self colorUsingCalibratedRGBColorSpace];
    float r=0,g=0,b=0,a=0;

    [color getRed:&r green:&g blue:&b alpha:&a];
    //float grayScale=r*0.299+g*0.587+b*0.114;
    float grayScale=r*0.2126+g*0.7152+b*0.0722;

    return [NSColor colorWithCalibratedRed:grayScale green:grayScale blue:grayScale alpha:a];
    }


    La première formule (maintenant en commentaire) fonctionnait bien jusqu'à  panther ou tiger, mais maintenant c'est la deuxième qui semble la plus exacte.


  • AliGatorAliGator Membre, Modérateur
    @mpergand :

    1) Pourquoi ne pas utiliser "colorWithCalibratedWhite:alpha:" plutôt que "colorWithCalibratedRed:green:blue:alpha:" ? Une raison particulière ?

    2) Le fait que tu aies eu à  changer la formule c'est sans doute parce que tu utilise des CalibratedColorSpaces et que le calibrage a changé entre avant et après Panther/Tiger, non ? Avec un DeviceColorSpace cela n'aurait sans doute pas été le cas ?

    3) Et je repose ma question, pourquoi utiliser RGB et faire ensuite le calcul du grayScale soi-même ?! Pourquoi ne pas convertir la couleur dans l'espace NS[Calibrated|Device][White|Black]ColorSpace tout simplement ? (ce qui va convertir ta couleur en niveaux de gris normalement, ce que fait donc ta méthode sauf qu'on utilise les méthodes Cocoa existantes déjà  faites pour ça) ?

    Moi j'aurais bien tenté un truc comme ça :
    - (NSColor*)contrastColor
    {
    NSColor* grayColor = [self colorUsingColorSpaceName:NSCalibratedWhiteColorSpace];

    float white, alpha;
    [grayColor getWhite:&white alpha:&alpha];

    CGFloat contrastWhite = (white<0.5) ? 1.0 : 0.0;
    return [NSColor colorWithCalibratedWhite:contrastWhite alpha:alpha];
    }
    Mais après j'ai pas testé, peut-être qu'il y a une subtilité qui fait que ça marche pas ou ne rend pas le résultat attendu ?
  • mpergandmpergand Membre
    janvier 2014 modifié #6

    En exclusivité pour toi, voici le code complet:



    return [NSColor colorWithCalibratedRed:grayScale green:grayScale blue:grayScale alpha:a];
    //return [NSColor colorWithCalibratedWhite:grayScale alpha:a];
    }

    Avec un DeviceColorSpace cela n'aurait sans doute pas été le cas ?

     



     


    Non, c'est pire.


  • AliGatorAliGator Membre, Modérateur
    janvier 2014 modifié #7
    Ah ben mince et pourquoi ça marche pas avec CalivratedWhite, ça donne pas la couleur attendue ?

    Je veux bien imaginer que RGB(x,x,x) != White(x) car ce ne sont pas les mêmes ColorSpaces, mais j'avoue que j'ai du mal à  bien capter pourquoi la valeur de greyScale que tu calcules (je reconnais les formules de conversions RGB/Grayscale qu'on trouve un peu partout) ne corresponde justement pas à  la valeur à  utiliser pour White(x)...

    Je n'ai toujours pas la réponse de pourquoi faire le calcul soi-même plutôt qu'utiliser les méthodes de conversion de ColorSpace que fournit Cocoa pour le faire, il y a certainement une raison mais ça m'intrigue de savoir laquelle ;)
  • CéroceCéroce Membre, Modérateur

    2) Le fait que tu aies eu à  changer la formule c'est sans doute parce que tu utilise des CalibratedColorSpaces et que le calibrage a changé entre avant et après Panther/Tiger, non ? Avec un DeviceColorSpace cela n'aurait sans doute pas été le cas ?

    Si, pour moi ça explique tout à  fait. Je crois me souvenir que le "gamma" de l'écran, auparavant à  2,2, est passé à  1,8 sous Tiger (pour faire comme sous Windows).
Connectez-vous ou Inscrivez-vous pour répondre.