[Swift] Lecture d'une image jpeg à  partir d'un fichier RTFD

DrakenDraken Membre
juin 2015 modifié dans API UIKit #1

J'ai voulu accéder à  une image jpeg contenue dans un fichier RTFD. A priori, c'est facile, il suffit de récupérer le NSTextAttachment correspondant et de lire sa propriété .image. ça marche très bien, sauf que là  .. non !


 


Après quelques tâtonnements, j'ai compris que NSTextAttachment fonctionne différemment selon que le texte soit créé en mémoire, ou lu à  partir d'un fichier RTFD. Petit programme d'exemple, bricolé dans l'urgence pour tenter de comprendre le truc :



//
// ViewController.swift
// LoadImageRTFD
//

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let textView = UITextView(frame: self.view.frame)
self.view.addSubview(textView)

let textSansImageRTFD = loadRTFD("textSansImage")
let ajout = NSTextAttachment()
ajout.image = UIImage(named: "unchat")
textSansImageRTFD.appendAttributedString(NSAttributedString(attachment: ajout))

let textAvecImageRTFD = self.loadRTFD("textAvecImage")

// let test = textSansImageRTFD
let test = textAvecImageRTFD

self.ajusterImage(test)
textView.attributedText = test

}

func ajusterImage(texte:NSMutableAttributedString) {
texte.enumerateAttribute(NSAttachmentAttributeName, inRange: NSMakeRange(0, texte.length), options: NSAttributedStringEnumerationOptions(0)) { (value, range, stop) -> Void in
if let textAttachement = value as? NSTextAttachment {
let image = textAttachement.image
if image == nil {
println("image nil")
println(textAttachement.fileType)
} else {
println(image!.size)
println(textAttachement.fileType)
let newImage = self.resizeImage(image!, reduction: 0.2)
let att = NSTextAttachment()
att.image = newImage
texte.removeAttribute(NSAttachmentAttributeName, range: range)
texte.addAttribute(NSAttachmentAttributeName, value: att, range: range)
}
}
}
}

func loadRTFD(nom:String) -> NSMutableAttributedString {
var error:NSErrorPointer = NSErrorPointer()
let urlFichier = NSBundle.mainBundle().URLForResource(nom, withExtension: "rtfd")
let monRTF = NSMutableAttributedString(fileURL: urlFichier,
options: [NSDocumentTypeDocumentAttribute:NSRTFDTextDocumentType],
documentAttributes: nil,
error: error)
return monRTF!
}

func resizeImage(image: UIImage, reduction: CGFloat) -> UIImage {

let newSize = CGSizeMake(image.size.width*reduction, image.size.height*reduction)
let rect = CGRectMake(0, 0, newSize.width, newSize.height)

UIGraphicsBeginImageContext(newSize)
image.drawInRect(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}

}


J'ai deux NSMutableAttributedString, l'une avec une image (un chat) ajoutée par le code, et l'autre avec une image(un bonhomme de neige) incluse directement dans le fichier RTFD.


 


La méthode ajusterImage() est censé parcourir la chaà®ne pour modifier la taille des images rencontrés.


 


textSansImageRTFD => ajusterImage() trouve bien l'image du chat. fileType contient nil.


 


textAvecImageRTFD => l'image vaut nil, et fileType contient Optionnel("public.jpeg"). Pourtant le fichier s'affiche correctement dans le UITextView, avec la bonne image (le bonhomme de neige).


 


Si j'ai bien compris, il faut utiliser fileWrapper pour récupérer l'image, mais je ne trouve pas la bonne manière de s'en servir, depuis .. outch .. 17 heures de l'après-midi !    


 


L'idée est d'ajuster la taille de l'image en fonction du device. Il y a peut-être un moyen plus simple de faire ça. Quelqu'un a une suggestion ? 


 


Allliiiiiiii au secours !


 


 


 


Réponses

  • AliGatorAliGator Membre, Modérateur
    mai 2015 modifié #2
    Qu'est ce que tu n'arrives pas à  utiliser au juste dans NSFileWrapper ?

    Perso je ne suis pas sûr de l'avoir utilisé un jour, mais la doc semble laisser penser que ça ne doit pas être bien sorcier.

    En fait, un fichier RTFD n'est rien d'autre qu'un bundle (tu peux faire "Afficher le contenu du paquet" via un clic droit dans le Finder, tu verras), contenant à  la fois le texte (fichier "TXT.rtf") et les pièces jointes (images dans des fichiers JPG, etc).

    Donc quand tu lis un fichier RTFD dans un NSAttributedString, du coup les NSTextAttachment ne sont que des pointeurs vers les pièces jointes dans le bundle du paquet du "RTFD". C'est ce que sont les NSFileWrapper, d'après ce que je lis dans la doc, ce sont des sortes de "pointeurs vers un emplacement sur disque" (soit un fichier, soit un dossier, soit un lien symbolique, cf le paragraphe d'introduction dans la doc de NSFileWrapper)

    Du coup si tu regardes la propriété "fileWrapper" de ton NSTextAttachment, tu devrais y voir un objet NSFileWrapper. Cet objet NSFileWrapper est très certainement un FileWrapper de type "regular file" " puisqu'il va à  priori pointer vers un fichier (JPG), et non vers un dossier ou un lien symbolique " dont la propriété regularFile (Bool) va donc certainement retourner true, la propriété "filename" pointera vers le fichier "12345.jpg" qui se trouve dans ton bundle ".rtfd", et la propriété "regularFileContents" devrait alors te permettre d'accéder au contenu (NSData) de ce fichier joint (JPG).
     
    private func image(fromAttachment txtAtt: NSTextAttachment) -> UIImage? {
    var image = txtAtt.image
    if image == nil {
    if let fileWrapper = txtAtt.fileWrapper where fileWrapper.regularFile {
    if let fileData = fileWrapper.regularFileContents {
    image = UIImage(data: fileData)
    }
    }
    }
    return image
    }
    Usage:
    ... // on suppose que tu as ton textAttachment dont tu veux extraire l'image
    if let image = self.image(fromAttachment: textAttachment) {
    println(image!.size)
    println(textAttachement.fileType)
    let newImage = self.resizeImage(image!, reduction: 0.2)
    let att = NSTextAttachment()
    att.image = newImage
    texte.removeAttribute(NSAttachmentAttributeName, range: range)
    texte.addAttribute(NSAttachmentAttributeName, value: att, range: range)
    } else {
    // Traitement du cas d'erreur où on n'a pas pu extraire l'image du NSTextAttachment
    // (car en fait ce n'est pas une image mais un autre type de pièce-jointe, par exemple)
    }
    PS : Idéalement on devrait même tester si "UTTypeConformsTo(textAttachment.fileType!, kUTTypeImage)" retourne true (NB : il faut "import MobileCoreService" pour pouvoir appeler la fonction UTTypeCOnformsTo) pour s'assurer que le NSTextAttachment est bien un type compatible avec le type "image" (que ce soit du JPEG, PNG, etc)... avant d'essayer d'en faire une UIImage.
    Voir cette page de la doc Apple pour + d'infos sur les types UTI.

    Bon, au pire, "UIImage(data: fileData)" étant un failable initializer, il retournera nil s'il n'a pas réussi à  créer l'image à  partir des NSData (mais bon c'est un peu bête d'aller lire tout les NSData de la pièce jointe si on sait d'avance via le fileType que ce n'est pas une image ;) donc tester le fileType peut être une bonne optimisation quand même)


    ---

    PS : Présentation alternative : utiliser une extension pour étendre le type NSTextAttachment et lui rajouter une propriété imageFromFile (plutôt que d'avoir une méthode privée dans ta classe)
    extension NSTextAttachment {
    func imageFromFile() -> UIImage? {
    var image : UIImage? = nil
    if let fileWrapper = txtAtt.fileWrapper where fileWrapper.regularFile {
    if let fileData = fileWrapper.regularFileContents {
    image = UIImage(data: fileData)
    }
    }
    return image
    }
    }
    Ce qui permet en + ensuite d'utiliser l'opérateur ternaire "??" (équivalent de "?:" en C et Objective-C), ainsi la fonction privée "image(fromAttachment: )" deviendrait tout simplement :
    let image = textAttachment.image ?? textAttachment.imageFromFile
    ---

    Note : aucun de ce code tapé ici n'a été testé, je te laisse ajuster en cas d'erreur de frappe ou autre.
  • DrakenDraken Membre

    Merci, je regarde ça demain. Là , dodo ..

  • LarmeLarme Membre

    Du coup, je suis également intéressé par la solution, plus par curiosité qu'autre chose.


     


    On avait déjà  parlé ici d'un soucis avec les NSTextAttachment dont les infos étaient différentes en fonction de si elle étaients loadées manuellement ou depuis un URL (via du HTML to NSAttributedString par example).


    Une solution un peu plus clean (mais en Objective-C avec des crochets qui te font cauchemarder Draken) sur SO.


     


    Donc ton problème relève peut-être d'une nouvelle subtilité dans la récupération des image sur un NSAttributedString, donc ça titille ma curiosité tout ça.

  • DrakenDraken Membre
    mai 2015 modifié #5

    ça marche !  :D


    Y compris quand l'image est du .png . C'était logique en regardant le code, mais rien ne vaut un vrai test en situation réelle.


  • DrakenDraken Membre
    mai 2015 modifié #6

    Question subsidiaire : y a-t-il un moyen de lire la taille de l'image sans la charger entièrement ? j'ai trouvé le moyen d'ajuster la taille d'un NSTextAttachment sans redimensionner l'image, en jouant sur la propriété bounds. 




    if let textAttachement = value as? NSTextAttachment {
    // LECTURE IMAGE
    /*
    var image = textAttachement.image
    if image == nil {
    // println(textAttachement.fileType)
    if let fileWrapper = textAttachement.fileWrapper where fileWrapper.regularFile {
    if let fileData = fileWrapper.regularFileContents {
    image = UIImage(data: fileData)
    }
    }
    }
    */
    // contrainteH est la largeur de l'image
    textAttachement.bounds = CGRectMake(0, 0, contrainteH, contrainteH/1.5)
    }


    Cet exemple ne marche correctement qu'avec des images ayant un rapport largeur/hauteur de 1,5. Pour que cela fonctionne avec des images de n'importe quelle dimension j'ai besoin de connaà®tre leurs tailles. D'où ma question: est-il possible de lire la taille d'un fichier image sans devoir le charger entièrement en mémoire ?

  • AliGatorAliGator Membre, Modérateur
    Avec le framework ImageIO je crois que tu peux oui.
  • DrakenDraken Membre
    mai 2015 modifié #8

    J'ai écrit une extension pour récupérer la taille d'un NSTextAttachment.



    extension NSTextAttachment {
    var size : CGSize? {
    var image = self.image
    if image == nil {
    if let fileWrapper = self.fileWrapper where fileWrapper.regularFile {
    if let fileData = fileWrapper.regularFileContents {
    image = UIImage(data: fileData)
    }
    }
    }
    return image?.size
    }
    }


    Ce qui allége considérablement le code pour ajuster l'affichage du NSTextAttachment :




    if let textAttachement = value as? NSTextAttachment {
    if let size = textAttachement.size {
    let scale = size.height/size.width
    textAttachement.bounds = CGRectMake(0, 0, contrainteH, contrainteH*scale)
    }
    }


  • AliGatorAliGator Membre, Modérateur
    C'est très dommage d'avoir écrit une extension qui ne retourne que la CGSize, alors que tu vas certainement avoir également besoin de la UIImage d'origine elle-même, et qu'il serait bête de devoir aller la relire une 2ème fois du disque dans un autre code !

    Pourquoi donc ne pas avoir utilisé l'extension de NSTextAttachment que j'ai proposé quelques posts plus haut (à  la fin du #2) pour récupérer la "UIImage?" ? Et ensuite tu as la UIImage, tu peux en faire ce que tu veux, dont récupérer sa CGSize (image?.size) mais aussi avoir directement l'image pour la redimensionner.

    Car sinon avec ton extension tu lis l'image sur disque juste pour en extraire la CGSize, alors qu'ailleurs tu vas avoir besoin de l'image elle-même et va être obligé d'aller la relire sur disque, c'est un peu dommage !
  • DrakenDraken Membre
    mai 2015 modifié #10

    Rome ne s'est pas construite en un jour. ça avance petit à  petit. La preuve : 



    func sizeFichierJpeg(nom:String) -> CGSize {
    let url = NSBundle.mainBundle().URLForResource(nom, withExtension: "jpg")
    let imageSource = CGImageSourceCreateWithURL(url, nil)
    let imageDico = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as Dictionary
    let largeur = imageDico["PixelWidth"] as! CGFloat
    let hauteur = imageDico["PixelHeight"] as! CGFloat
    return CGSizeMake(largeur, hauteur)
    }


    Un petit pas pour l'homme, un grand pour moi. Bon, reste plus qu'à  connecter ça à  un NSTextAttachment.


  • Finish ! * croise les doigts *


    J'ai passé un temps fou à  essayer de récupérer l'url du NSTextAttachment, alors qu'il suffisait de créer une imageSource à  partir de fileWrapper.regularFileContents.



    extension NSTextAttachment {
    var size : CGSize {
    var image = self.image
    var size = CGSizeZero
    if image == nil {
    if let fileWrapper = self.fileWrapper where fileWrapper.regularFile {
    let url = fileWrapper.filename
    if let fileData = fileWrapper.regularFileContents {
    let imageSource = CGImageSourceCreateWithData(fileData, nil)
    let imageDico = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as Dictionary
    let largeur = imageDico[kCGImagePropertyPixelWidth as String] as! CGFloat
    let hauteur = imageDico[kCGImagePropertyPixelHeight] as! CGFloat
    size = CGSizeMake(largeur, hauteur)
    }
    }
    } else { size = image!.size }
    return size
    }
    }


    Note pour les personnes voulant utiliser ce code: ne pas oublier d'importer le framework imageIO.

  • AliGatorAliGator Membre, Modérateur
    mai 2015 modifié #12
    Mais... mais... mais NON !!!


    1) Comme dit plus haut, c'est pas malin de récupérer fileWrapper.regularFileContents (qui va aller lire le contenu du fichier sur disque, donc charger en mémoire l'intégralité du NSData représentant le contenu du disque) dans la méthode "size" au lieu de l'exposer séparément, car là  ton code ne calcule que la taille, et donc quand ailleurs tu vas avoir ton code qui va avoir vraiment besoin de l'image (pour la redimensionner, etc), tu vas devoir aller la relire sur le disque !

    Pourquoi ne pas segmenter tout ça pour permettre d'accéder à  chaque propriété, en particulier à  chaque étape intermédiaire, celle qui récupère la NSData, celle qui en extrait la size, et celle qui en extrait l'UIImage, pour qu'ainsi tu n'aies pas à  dupliquer le code qui va lire le NSData depuis le disque dans plusieurs méthodes (une pour avoir la CGSize, l'autre pour avoir la UIImage) ?

    2) Pourquoi ne pas faire des lazy vars, qui sont en plus carrément tout à  fait adapté à  cet usage, et vont permettre d'éviter de réexécuter le code qui va lire le contenu sur le disque à  chaque fois, alors que quand tu l'as lu une fois c'est pas la peine d'aller le relire à  chaque fois que tu vas accéder à  la propriété sinon ;) (Bon ceci dit, j'ai un doute, je ne suis pas sûr qu'on puisse faire une "lazy var"... dans une "extension", à  vérifier)
    [EDIT] Bon je viens de tester, et effectivement on ne peut pas faire de "lazy vars" dans une "extension", ce qui semble normal finalement car cela consisterait à  rajouter une stored property sous le capot, ce qu'on ne peut pas faire avec les extensions (tout comme on ne peut pas rajouter de variable d'instance à  une catégorie en ObjC)

    3) Quel est l'intérêt d'utiliser ImageIO si c'est pour lire les NSData depuis le disque ? L'intérêt d'utiliser ImageIO (plutôt que d'aller lire les NSData sur le disque, la transformer en UIImage et extraire sa size), c'est justement de ne pas à  avoir à  lire TOUT le fichier JPEG ou PNG ni à  le charger *entièrement* en mémoire juste pour déterminer la taille ! Or là  c'est justement ce que tu fais, tu charges toute la NSData en mémoire, du coup utiliser ImageIO derrière (comparativement à  "UIImage(data:...)?.size") perd totalement de son intérêt !
  • AliGatorAliGator Membre, Modérateur
    mai 2015 modifié #13
    Tu étais bien plus proche d'un code propre avec ton code du post #10 (qui utilise bien ImageIO à  partir d'une URL sans charger en mémoire le contenu du fichier du disque " mais qui ne va juste pas le chercher au bon endroit car il construit mal l'URL) qu'avec ton post #11 (qui va lire le contenu du fichier sur disque, ce qui enlève complètement tout l'intérêt d'utiliser ImageIO dont le seul but était d'éviter justement d'avoir à  lire tout le fichier)

    Dans ton post #10, le seul truc c'est que tu construis ton URL avec "NSBundle.mainBundle().URLForResource(...)"... comme si le fichier en question était dans les ressources de ton MainBundle (donc dans les ressources de ton propre projet), alors que le fichier que tu cherches à  lire c'est un fichier qui est à  l'intérieur du paquet ".rtfd", rien à  voir avec le bundle de ton app.

    Au lieu de ça, il suffit d'utiliser la propriété "filename" du NSFileWrapper associé à  ton NSTextAttachment), qui te donne un chemin sur le disque (String), et de le transformer en NSURL via la méthode de classe NSURL.fileURLWithPath().
     
    private func sizeOfImageAtPath(path: String) -> CGSize? {
    var imageSize = CGSizeZero
    if let imageURL = NSURL.fileURLWithPath(path),
    let imageSource = CGImageSourceCreateWithURL(imageURL as CFURLRef, nil) {
    let imageDico = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as Dictionary
    let largeur = imageDico[kCGImagePropertyPixelWidth as String] as! CGFloat
    let hauteur = imageDico[kCGImagePropertyPixelHeight] as! CGFloat
    imageSize = CGSize(width: largeur, height: hauteur)
    }
    return imageSize
    }

    extension NSTextAttachment {
    var imageSize : CGSize? {
    var imgSize : CGSize?
    if let size = self.image?.size {
    imgSize = size
    } else if let path = self.fileWrapper?.filename {
    // This *won't* load the image data into memory
    imgSize = sizeOfImageAtPath(path)
    }
    return imgSize
    }

    // Read the image from the disk
    var imageFromFile : UIImage? {
    var image : UIImage? = nil
    if let fileWrapper = txtAtt.fileWrapper where fileWrapper.regularFile {
    if let fileData = fileWrapper.regularFileContents {
    image = UIImage(data: fileData)
    }
    }
    return image
    }
    }
    Utilisation :
    let txtAtt : NSTextAttachment = ...

    txtAtt.imageSize // will return the image size, without even loading it from disk even if it's not in memory yet
    txtAtt.image // can be nil if image is located on disk and not created in memory
    txtAtt.imageFromFile // will load image from disk. May be nil if the attachment is not actually an image
  • DrakenDraken Membre
    mai 2015 modifié #14

    Je ne m'occupe pas de l'affichage, je balance un NSAttributedString à  un UITextView qui se débrouille tout seul, avec ces propres optimisations. Je présume (peut-être naà¯vement) qu'il est préférable de donner les NSTextAttachment sous forme de référence vers des images disque, que sous forme d'une UIImage. L'idée est d'afficher un long texte dans un UITextView avec plusieurs images.  


     


    J'avais cru comprendre qu'une CGImageSource était une référence vers un fichier, et non le fichier complet. Ce n'est peut-être le cas que pour CGImageSourceCreateWithURL. Je n'avais pas compris que fileWrapper.regularFileContents chargeait l'intégralité du fichier en mémoire. 


     


    J'ai testé les deux techniques sur mon iPhone 4. Il n'y a aucune différence visible entre les deux méthodes de chargement, même avec une quinzaine d'images dans un texte copieux.


     


    Si tu penses que ce n'est pas une bonne idée, je laisse tomber pour suivre ton conseil et convertir les images en UIImage. J'espérais vraiment arriver à  lire la taille d'un NSTextAttachment sans charger toute l'image, pour laisser le UITextView s'occuper du chargement à  sa sauce, forcément plus optimisé que la mienne, mais tant pis. Je ne vais pas perdre des jours sur ce problème. 


     


    EDIT : Tu as posté alors que j'écrivais ma réponse. J'ai essayé d'utiliser filename, mais il semblais ne donner qu'un nom interne au package RTFD et non un path complet. D'ailleurs, les posts traitant du sujet dénichés par Google semblent arriver à  la même conclusion que moi. Manifestement, nous, les noobs, sommes légions sur le net.


     


    Merci d'avoir répondu à  mon problème. Je ne serais jamais à  l'aise avec la programmation système, c'est évident. 

  • AliGatorAliGator Membre, Modérateur

    J'avais cru comprendre qu'une CGImageSource était une référence vers un fichier, et non le fichier complet. Ce n'est peut-être le cas que pour CGImageSourceCreateWithURL. Je n'avais pas compris que fileWrapper.regularFileContents chargeait l'intégralité du fichier en mémoire.

    Oui ce n'est le cas que pour CGImageSourceCreateWithURL... pour une raison très simple, c'est que l'autre (CGImageSourceCreateWithData) tu lui passes un NSData... donc ce NSData, faut déjà  l'avoir, donc faut bien qu'il ait lu ces NSdata depuis le disque à  ce moment là  ! C'est d'ailleurs aussi logique pour fileWrapper.regularFileContents, qui retourne un NSData... comment il pourrait te retourner un NSData en retour de la propriété... sans avoir lu lesdites données depuis le disque ?
     

    J'ai testé les deux techniques sur mon iPhone 4. Il n'y a aucune différence visible entre les deux méthodes de chargement, même avec une quinzaine d'images dans un texte copieux.

    Ca ne m'étonne pas trop en pratique, car même sur un iPhone 4, la lecture sur disque est certainement rapide dans l'ensemble. Par contre je serait curieux de voir ce que ça donne si tu lis un fichier RTFD... qui contient des *grosses* images (surtout si elles sont en JPG, qui est moins optimisé sur iOS que le PNG à  ma connaissance, qui lui est le format de prédilection pour iOS) ; genre un RTFD dont les fichiers images qui se trouvent dans son paquet font plusieurs Mo (et qu'il y en a plusieurs, de surcroit).

    Après, ça doit pas non plus arriver tous les jours et du coup vu que dans la plupart des cas les fichiers image à  lire sont de taille modérée et que la lecture sur disque reste pas non plus si longue que ça, ça ne doit pas non plus se ressentir un max si tu relis le fichier du disque en entier à  chaque fois. Mais dans ce cas je ne vois pas l'intérêt d'aller se compliquer la vie avec ImageIO (alors que le code pour utiliser ImageIO est un peu plus dur à  appréhender que directement utiliser UIImage), alors que le but de passer à  ImageIO était justement d'éviter d'aller lire tout le fichier sur disque justement !
     

    Si tu penses que ce n'est pas une bonne idée, je laisse tomber pour suivre ton conseil et convertir les images en UIImage. J'espérais vraiment arriver à  lire la taille d'un NSTextAttachment sans charger toute l'image, pour laisser le UITextView s'occuper du chargement à  sa sauce, forcément plus optimisé que la mienne, mais tant pis. Je ne vais pas perdre des jours sur ce problème.

    Bah justement non, c'est une bonne idée d'essayer de lire la taille de l'image sans avoir à  charger toute l'image, mais ce que je disais c'est que justement là  ton code précédent bah il chargeait toute l'image. Si tu veux éviter de charger toute l'image pour avoir sa taille, il ne faut ni utiliser UIImage ni CGImageSourceCreateWithData, mais utiliser CGImageSourceCreateWithURL.


    EDIT : Tu as posté alors que j'écrivais ma réponse. J'ai essayé d'utiliser filename, mais il semblais ne donner qu'un nom interne au package RTFD et non un path complet. D'ailleurs, les posts traitant du sujet dénichés par Google semblent arriver à  la même conclusion que moi. Manifestement, nous, les noobs, sommes légions sur le net.

    Ah. En effet, j'avoue ne pas du tout avoir testé le code que j'ai écrit ici.

    Bon, bah en effet faut le savoir que filename n'est que le nom du fichier et pas son path " en même temps j'aurais quand même pu mieux lire la doc et surtout m'en douter, la propriété s'appelle "filename" (soit "nom du fichier") et pas filepath, après tout.

    Mais qu'à  cela ne tienne, maintenant qu'on sait ça, il suffit de construire la NSURL en conséquence qui va pointer sur ce fichier. C'est donc la NSURL pointant sur ton fichier RTFD (genre "NSURL.fileURLWithPath(pathToRTFDFile)"), à  laquelle tu concatènes ("URLByAppendingPathComponent(...)") ce fameux "filename".
    Comme ça tu obtiens une NSURL (qui est une URL représentant un chemin sur ton disque, donc sans doute du type "file:///Users/toi/Documents/...") qui pointe vers le fichier nommé "filename" à  l'intérieur du bundle ".rtfd" en question, et tu peux ensuite utiliser avec CGImageSourceCreateWithURL.
  • DrakenDraken Membre
    juin 2015 modifié #16

    Je viens de m'y remettre. ça marche en ajoutant le path du fichier RTFD "container" au nom interne dans le paquet. Merci Ali !


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