Réduite taille mémoire d'une NSImage

Bonjour,


 


Je réalise une application pour un membre de ma famille qui souhaite gérer les livres de sa bibliothèque. Vous me direz qu'il existe déjà  une application pour ça mais j'ai besoin de faire plus simple.


 


Mon problème est le suivant : pour chaque livre j'ai la possibilité de stocker l'image de la page de garde. Bien sûr selon la méthode de production des images par l'utilisateur (scan, photo, web...) j'aurai des tailles de 200Ko à  12Mo. Pour quelques livres pas de problème, mais pour 1600 ça commence a peser lourd ! Une qualité médiocre reste lisible et largement suffisante.


 


Je souhaite filtrer les image et réduire leur taille mémoire (avant éventuelle décompression) lors de l'import. Peut-être tout passer en JPEG avec un taux de compression adapté ?


 


Je n'ai pas trouvé de méthode adaptée. Avez-vous une idée pour réaliser la chose ?


 


Merci d'avance.


Réponses

  • DrakenDraken Membre
    juillet 2015 modifié #2

    C'est clair que tes images doivent être en jpg, pour économiser la mémoire. Sous iOS il y a UIImageJPEGRepresentation permettant de sauver des images sur disque au format jpeg en précisant le facteur de compression. Je présume qu'il doit y avoir l'équivalent en OSX. 


     


    Tu peux aussi modifier la taille de l'image avant de la sauver. Pas besoin d'archiver 2000x2000 pixels si 640x480 suffisent pour ton logiciel (exemple purement fictif, tout dépend du design de ton application, une image plein écran étant plus volumineuse qu'une vignette).


  • Salut,


     


    http://nshipster.com/image-resizing/


     


    J'avais fais face au même problème il y a un an et Ali si je me souviens bien m'avait donné ce lien ci-dessus qui pourrait t'être utile. Pour ma part j'avais utilisé i/o qui me permettait de charger des images avec une qualité bien inférieure mais avec l'avantage d'être moins lourd à  charger.


  • A titre d'exemple, une fonction écrite en Swift pour changer la taille d'une image :



    func resizeImage(image: UIImage, scale: CGFloat) -> UIImage {
    let newSize = CGSizeMake(image.size.width*scale, image.size.height*scale)
    let rect = CGRectMake(0, 0, newSize.width, newSize.height)
    UIGraphicsBeginImageContext(newSize)
    image.drawInRect(rect)
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
    }


    Il s'agit juste de dessiner une image dans un contexte graphique et de récupérer le bitmap résultant.

  • CéroceCéroce Membre, Modérateur

    Sauf que ça ne marche pas si l'image subit une rotation virtuelle (rotation EXIF) ce qui est le cas quand on prend une photo avec la caméra de l'iPhone.


    Heureusement, l'ami Aligator a tout prévu.


  • Merci à  tous pour vos réponses.


    Je biens de faire un petit stage à  l'hôpital et reprends la conversation avec du retard.


    Lorsque je parlais de réduire la taille d'une image je parlais d'en réduite la taille mémoire au moyen d'une compression.

  • http://stackoverflow.com/questions/3038820/how-to-save-a-nsimage-as-a-new-file ?

    Il y a apparemment une property (à  mettre dans un NSDictionary) qui permet de setter une compression.


  • Perso, je réduis la taille de l'image avec CIImage, par exemple comme ceci :



    float coeffReduction;
    CIImage *iCopiePourReduction = [[CIImage alloc] initWithData:[uneImage TIFFRepresentation]];
    CIImage *iCopiePourReduction2b = [iCopiePourReduction imageByApplyingTransform:CGAffineTransformMakeScale (coeffReduction, coeffReduction)];

    Du coup, ayant moins de pixels, elle est moins gourmande en mémoire.


  • AliGatorAliGator Membre, Modérateur
    Heu sortir l'artillerie lourde de CoreImage juste pour ça c'est un peu violent quand même. Si tu utilises CoreImage déjà  pour d'autres choses genre pour faire des traitements d'image ou des effets plus poussées, pourquoi pas, tant que t'es dedans... mais si tu l'utilises juste pour ça c'est un peu le bulldozer pour tuer une mouche non ?
  • Je ne sais pas. Les traitements de CIImage sont instantanés, le framework me semble le plus adapté dès qu'il faut un traitement. 



  • let oldImage = UIImage(named: "image.png")
    let imageDataCompressed = UIImageJPEGRepresentation(oldImage, 0.5)
    let newImage = UIImage(data: imageDataCompressed)

    Et en essayant ça ?


  • Je traduit en ObjectiveC et je teste.


    Merci.


  • Ha oui pardon, en Objective-C ça donnerai ça :



    UIImage *oldImage = [UIImage imageNamed:@image.png];
    NSData *imageDataCompressed = UIImageJPEGRepresentation(oldImage, 0.5);
    UIImage *newImage = [UIImage imageWithData:imageDataCompressed];
  • Si la classe UIImage possède la bonne méthode, évidemment...


Connectez-vous ou Inscrivez-vous pour répondre.