"Rasteriser" une image vectorielle
Antilog
Membre
Bonjour à tous,
Je reviens avec une question sur les images, mon casse-tête favori.
Le besoin est celui-ci :
A partir de n'importe quel type d'image lisible directement par NSImage, je voudrais créer un fichier texte décrivant en hexadécimal chaque pixel de l'image, en RVB 256 nuances par composant : donc un pixel sera décrit entre 000000 et FFFFFF.
Voilà ci-dessous ce que j'ai écrit, et qui fonctionne dans certains cas, avec mes commentaires pour l'occasion
C'est normal que j'ai tout mis dans l'awakeFromNib, car c'est juste pour l'instant un test sur le moteur lui-même, l'interface n'existe pas encore! ! !
Alors, ça fonctionne... dans certains cas.
Pour une image GIF 256 couleurs , c'est impeccable, ça transcrit les couleurs indexées en valeurs RVB.
Pour une image TIFF 65535 couleurs, c'est également OK
Pour une image PDF, par contre, ça bloque, il semble que malgré tous mes efforts pour rasteriser le dessin, il n'en fasse qu'à sa tête. Par contre, un pdf constitué simplement d'une image bitmap fonctionne. Quelqu'un a une explication ? Ou une méthode pour arriver à mes fins ?
Merci d'avance
Je reviens avec une question sur les images, mon casse-tête favori.
Le besoin est celui-ci :
A partir de n'importe quel type d'image lisible directement par NSImage, je voudrais créer un fichier texte décrivant en hexadécimal chaque pixel de l'image, en RVB 256 nuances par composant : donc un pixel sera décrit entre 000000 et FFFFFF.
Voilà ci-dessous ce que j'ai écrit, et qui fonctionne dans certains cas, avec mes commentaires pour l'occasion
C'est normal que j'ai tout mis dans l'awakeFromNib, car c'est juste pour l'instant un test sur le moteur lui-même, l'interface n'existe pas encore! ! !
- (void)awakeFromNib <br />{ <br /> inputImage = [NSImage imageNamed:@"TOTO"]; <br /> // lockFocus/unlockFocus pour génèrer le NSCachedImageRep , probablement pas utile ici<br /> [inputImage lockFocus]; <br /> [inputImage unlockFocus]; <br /> <br /> NSSize sz = [inputImage size]; <br /> int w = (int)sz.width; <br /> int h = (int)sz.height; <br /> <br /> // Création d'une représentation avec les param. qu'il me faut : <br /> // même taille que l'image d'origine, 8 bits par composant <br /> NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] <br /> initWithBitmapDataPlanes: NULL <br /> pixelsWide: w <br /> pixelsHigh: h <br /> bitsPerSample: 8 <br /> samplesPerPixel: 4 <br /> hasAlpha: YES <br /> isPlanar: NO <br /> colorSpaceName: NSCalibratedRGBColorSpace <br /> bytesPerRow: 0 <br /> bitsPerPixel: 32]; <br /><br /> // Copie de l'image d'origine dans ma nouvelle représentation, <br /> // Afin qu'elle s'adapte : augmentation du nombre de couleurs ou au <br /> // contraire, perte de couleurs, passage en RVBA, rasterisation si besoin <br /> // Il faut que l'imageRep ait une couche alpha, sinon ça ne fonctionne pas!!?? <br /><br /> NSGraphicsContext* gc = [NSGraphicsContext graphicsContextWithBitmapImageRep:imageRep]; <br /> [NSGraphicsContext saveGraphicsState]; <br /> [NSGraphicsContext setCurrentContext:gc]; <br /> [[NSColor whiteColor] set]; <br /> [[NSBezierPath bezierPathWithRect:NSMakeRect(0.0, 0.0, w, h)] fill]; <br /> [inputImage drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0.0, 0.0,w,h) operation:NSCompositeCopy fraction:1.0f]; <br /> <br /> [NSGraphicsContext restoreGraphicsState]; <br /> outputImage = [[NSImage alloc] initWithSize:sz]; <br /> [outputImage addRepresentation:imageRep]; <br /> [imgWell setImage:outputImage]; <br /><br /> //Création de la chaà®ne de caractères définissant les pixels en hexa <br /> NSBitmapImageRep* btmpImageRep = [NSBitmapImageRep imageRepWithData:[outputImage TIFFRepresentation]]; <br /> <br /> unsigned char * data = [btmpImageRep bitmapData]; <br /> int bpp = [btmpImageRep bitsPerPixel]/8; <br /> int bpr = [btmpImageRep bytesPerRow]; <br /> NSMutableString* hex = [[NSMutableString alloc] initWithCapacity:w*h*3+h*2]; <br /> unsigned char* p; <br /> int x,y; <br /> for (y=0 ; y<h ; y++) <br /> { <br /> p = data + y * bpr; <br /> for (x=0 ; x<w ; x++) <br /> { <br /> [hex appendFormat:@"%02X%02X%02X",*p, *(p+1), *(p+2)]; <br /> p+= bpp; <br /> } <br /> [hex appendString:@"\r\n"]; <br /> } <br /> [hex writeToFile:@"test.txt" atomically:YES encoding:NSWindowsCP1250StringEncoding error:NULL]; <br /><br />}
Alors, ça fonctionne... dans certains cas.
Pour une image GIF 256 couleurs , c'est impeccable, ça transcrit les couleurs indexées en valeurs RVB.
Pour une image TIFF 65535 couleurs, c'est également OK
Pour une image PDF, par contre, ça bloque, il semble que malgré tous mes efforts pour rasteriser le dessin, il n'en fasse qu'à sa tête. Par contre, un pdf constitué simplement d'une image bitmap fonctionne. Quelqu'un a une explication ? Ou une méthode pour arriver à mes fins ?
Merci d'avance
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Bon j'ai pas décortiqué ton code, et pourtant du peu que j'ai lu tu sembles essayer de rasteriser ton image dans un NSBitmapImageRep donc ça devrait effectuer la pixellisation, mais bon, doit y avoir un truc qui traà®ne.
Ce qui est le plus étonnant, c'est que l'image obtenue (outputImage) s'affiche bien dans une imageWell, mais la transformation en texte n'est pas correcte (en particulier le blanc est noir, et le reste est ... bizarre)
Sinon, il manque plusieurs "release" dans ce code.
1. Parce que je ne pense pas que je pourrais être maà®tre de la profondeur des couleurs
2. Ca ne m'étonne pas vraiment, je ne release rien du tout
Ce n'est pas grave, dans l'état actuel du "programme", il ne fait que ça: ouvrir une image de son bundle, la convertir, l'afficher et écrire le fichier ::)
Heu... Oui, j'aurais dû le faire directement, j'avais créé l'image afin d'afficher le résultat, mais je n'étais pas obligé de repartir de l'image... Merci
Par contre, j'ai testé entre temps, et un pdf créé à partir de Pages fonctionne "presque" correctement (presque car le dernier pixel de chaque ligne est à 515151).
Il semble donc que le pdf que j'utilise depuis le début est particulier (ce ne serait pas étonnant, il vient d'un PC). Je vais étudier de plus près ce qu'il a de spécial...
En fait, ça ne marche que si l'image est en 72 ppp.
Par contre, si ton image est en 300 ppp, il faudra multiplier les dimensions par 300/72. C'est le bordel, et c'est lié au fait qu'une NSImage peut contenir plusieurs représentations. Tu peux obtenir les vraies dimensions avec -[NSImageRep pixelsHigh] et pixelsWide.
Je te laisse réfléchir aux conséquences quand NSImage est issue d'un PDF, qui par définition, n'a pas de dimensions en pixels.
Il y a forcément une dimension par défaut indicative, sinon les logiciels qui l'ouvriraient ne sauraient plus où donner de la tête pour l'afficher
Comme le dit schlum, il y a forcément une dimension en pixels, même si elle est indicative. Elle doit correspondre à la dimension de la page (décrite dans le pdf en unités, avec une unité par défaut modifiable à 1/72 pouce).
Pour le fait de récupérer la dimension de l'image, ça ne me pose pas de problème particulier: comme c'est un pdf, je pourrais de toutes façons modifier la taille comme je veux, si besoin était.
En plus, si je pars de l'imageRep, il faudrait que je boucle sur toutes les éventuelles imageRep pour prendre une décision!
J'y reviens...
En fait, le pdf est particulier car le fond de page est transparent, et pas blanc comme le montrent Aperçu et Adobe Reader... >:D
Mais j'avais copié mon image sur un rectangle que j'avais exprès rempli de blanc, parce que j'avais pensé au cas où il y aurait de la transparence dans l'image...
Pourquoi ça ne marche pas??? :crackboom:-
Oups!!!
Désolé