Image et résolution

UniXUniX Membre
23:21 modifié dans API AppKit #1
Salut,

Une question relative aux images, et à  la façon dont on gère la résolution avec Cocoa.
A l'heure actuelle, lorsque je crée un NSImage à  partir d'un fichier, tout se passe bien si la résolution de l'image du fichier est 72ppp, moins bien si elle est différente.
Un exemple simple : j'ouvre une image de 1000x1000 pixels à  72ppp, la méthode size de NSImage me retourne bien 1000x1000. En revanche, si j'ouvre la même image qui cette fois-ci est en 144ppp, la méthode size me retourne 500x500.
En fait, lorsque les images ont une résolution supérieure à  72ppp, elles sont ramenées à  cette valeur en supprimant des pixels.

Le problème est que lorsqu'on affiche ensuite ces images, elles sont dégradées au niveau qualité, et ne font surtout plus les bonnes dimensions .....!

Comment faire pour obtenir des NSImages avec les résolutions d'origine ?


J'ai vu dans la doc que la taille retournée par size de NSImage est en fait la taille de l'image à  sa résolution. Le nombre de pixels s'obtient plutôt avec pixelsHigh et pixelsWide de NSImageRep, j'ai juste ?

J'ai un peu de mal à  percevoir les différences, surtout dans l'utilisation que l'on peut en faire, de NSImage et NSImageRep.

Faudrait-il que je dessinne plutôt le NSBitmapImageRep que le NSImage dans mes vues pour avoir les images aux bonnes dimensions ?

Réponses

  • BruBru Membre
    23:21 modifié #3
    NSImage n'est qu'un conteneur d'image. Rien d'autre.

    Ce conteneur stocke donc des images (les fameux NSImageRep) qui peuvent être de format et/ou résolution différents.
    Donc pour une image donnée, tu peux avoir une image bitmap (donc issu d'un tiff, jpeg ou autre) de basse résolution (72 ppp), une de hautre résolution (300 ppp), et enfin une dernière en vectorielle.

    Donc le NSImage contient ces 3 représentations d'une même image.
    C'est ensuite le système qui va choisir quelle représentation utiliser en fonction des caractéristiques du contexte graphique.
    Si le contexte est un écran (et dont sa résolution est 72ppp), NSImage retournera plutôt la représentation en basse résolution. Par contre, si c'est une imprimante de 1200ppp, la représentation utilisée sera la représentation vectorielle.

    Maintenant, si tu utilises directement NSImage pour créer une image à  partir d'un fichier, il y a de forte chance que la représentation d'image créée ne soit pas celle du fichier d'origine, mais une correspondant au contexte graphique courant (ou par défaut).

    Dans ce cas, pour éviter ça, tente de créer d'aborde le NSImageRep, puis ensuite créé le NSImage en y ajoutant ton imageRep.

    {
        NSBitmapImageRep *rep;
        NSImage *img;

        rep=[NSBitmapImageRep imageRepWithData:[NSData dataWithContentsOfFile:@image.jpg]];
        img=NSImage alloc] initWithSize:[rep size;
        ;    }.
  • schlumschlum Membre
    avril 2007 modifié #4
    dans 1176986081:

    [...]
    Maintenant, si tu utilises directement NSImage pour créer une image à  partir d'un fichier, il y a de forte chance que la représentation d'image créée ne soit pas celle du fichier d'origine, mais une correspondant au contexte graphique courant (ou par défaut).

    Dans ce cas, pour éviter ça, tente de créer d'aborde le NSImageRep, puis ensuite créé le NSImage en y ajoutant ton imageRep.

    {
        NSBitmapImageRep *rep;
        NSImage *img;

        rep=[NSBitmapImageRep imageRepWithData:[NSData dataWithContentsOfFile:@image.jpg]];
        img=NSImage alloc] initWithSize:[rep size;
        ;    }.


    Ca devrait donner le même résultat (la résolution est gérée par l'imageRep)...  ???
    Peut-être, en faisant :
    NSSize newSize;<br />	newSize.width = [[image bestRepresentationForDevice:nil] pixelsWide];<br />	newSize.height = [[image bestRepresentationForDevice:nil] pixelsHigh];<br />	[image setSize:newSize];
    

    (comme fait le gars sur la page dont j'ai donné le lien au-dessus...)
  • UniXUniX Membre
    23:21 modifié #5
    Merci Bru pour cette explication qui m'aide à  y voir un peu plus clair dans l'architecture image de Cocoa.
    D'ailleurs, le lien que donne Schlum tente également d'éclairer les lanternes. Je l'ai lu et essayé le code qui y est donné (celui que tu rappelles dans ton dernier message Schlum), et ça fonctionne parfaitement.

    J'ai également essayé ton code Bru, mais malheureusement ça ne fonctionne pas.
  • Philippe49Philippe49 Membre
    23:21 modifié #6
    Je suis tombé sur un problème analogue pour réagir à  un redimensionnement de la fenêtre. L'application mémorisant l'image transformée, le flou arrive très vite.

    Une solution qui semble marcher à  l'expérimentation :
    [image setCacheMode:NSImageCacheNever];


    setCacheMode:
    Set the receiver's caching mode.

    -(void)setCacheMode:(NSImageCacheMode)mode

    Parameters
    mode
    The caching mode to use with this image. For a list of possible values, see “Constants”.

    Discussion
    The caching mode determines when the receiver's image representations use offscreen caches. Offscreen caches speed up rendering time but do so by using extra memory. In the default caching mode (NSImageCacheDefault), each image representation chooses the caching technique that produces the fastest drawing times. For example, in the default mode, the NSPDFImageRep and NSEPSImageRep classes use the NSImageCacheAlways mode but the NSBitmapImageRep class uses the NSImageCacheBySize mode.

    For more information on image caching behavior, see the Images chapter of Cocoa
    Drawing Guide.



    Compte-tenu de ce que vous dites, est-ce que je passe à  côté d'un problème ?
Connectez-vous ou Inscrivez-vous pour répondre.