[HELP derechef : RESOLU] Enregistrer une CGImage en JPG

Philippe49Philippe49 Membre
janvier 2008 modifié dans API AppKit #1
Une fonction qui marche permet d'obtenir le point d'interrogation ci-dessous comme une CGImageRef
Je la mets pour mémoire, elle est bonne

CGImageRef backgroundCGImageRef(CGSize size)

CGImageRef backgroundCGImageRef(CGSize size)<br />{<br />	CGFloat width=size.width , height=size.height ;<br />	CGRect r=CGRectMake(0.,0.,width,height);<br />	size_t bytesPerRow = 4*width;<br />	size_t bitsPerComponent=8;<br />	CGColorSpaceRef colorspace=CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);<br />	CGBitmapInfo bitmapInfo=kCGImageAlphaPremultipliedFirst; <br />	void* bitmapData = malloc(bytesPerRow * r.size.height);<br />	CGContextRef context = CGBitmapContextCreate(bitmapData, width, height, bitsPerComponent,&nbsp; bytesPerRow, colorspace, bitmapInfo);<br />	NSGraphicsContext *ctx = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:YES];<br />	<br />	[NSGraphicsContext saveGraphicsState];<br />	[NSGraphicsContext setCurrentContext:ctx];<br />	CGContextSetRGBStrokeColor (context, 0., 0., 1., 0.7); <br />	CGContextSetRGBFillColor (context, 0., 0., 1., 0.7); <br />	CGContextSetLineWidth (context,5.0);<br />	CGContextBeginPath(context);<br />	CGFloat radius=MIN(width,height)*0.2;<br />	CGPoint center=CGPointMake(width*0.5,height*0.7);<br />	CGContextAddArc(context, center.x, center.y, radius, M_PI,-M_PI/6.,1);<br />	CGContextAddLineToPoint(context, center.x, center.y-radius*2.);<br />	CGFloat secondRadius=radius*2./sqrt(3.);<br />	CGContextAddArc(context, center.x+radius,&nbsp; center.y-(2.+1/sqrt(3.))*radius, secondRadius, 5.*M_PI/6., M_PI,0);<br />	CGContextAddLineToPoint(context, center.x+radius-secondRadius, center.y-3.*radius);<br />	CGContextStrokePath(context);<br />	CGFloat widthPoint=7.;<br />	CGContextFillEllipseInRect (context, CGRectMake (center.x+radius-secondRadius-widthPoint/2., center.y-4.*radius-widthPoint/2., widthPoint, widthPoint));	<br />	[NSGraphicsContext restoreGraphicsState];<br />	<br />	CGImageRef image = CGAutorelease(CGBitmapContextCreateImage(context));<br />	CGContextRelease(context);<br />//	free(bitmapData);<br />	return image;<br />}



J'ai piqué dans la doc et dans des exemples quelque chose comme ce qui suit, à  savoir une fonction sensée enregistrer mon image
bool CGWriteToURL(CGImageRef image,CFURLRef absURL, CFStringRef typeName)

<br />bool CGWriteToURL(CGImageRef image,CFURLRef absURL, CFStringRef typeName)<br />{<br />	bool status = false;<br />	<br />	// Make sure the image exists before continuing.<br />	if (image==nil){<br />		goto bail;<br />	}<br />	CGImageRetain(image);<br />	<br />	// making the options dictionary<br />	float compression = 1.0; // Lossless compression if available.<br />	int orientation = 4; // Origin is at bottom, left<br />	CFStringRef myKeys[3];<br />	CFTypeRef&nbsp; &nbsp;myValues[3];<br />	CFDictionaryRef myOptions = NULL;<br />	myKeys[0] = kCGImagePropertyOrientation;<br />	myValues[0] = CFNumberCreate(NULL, kCFNumberIntType, &amp;orientation);<br />	myKeys[1] = kCGImagePropertyHasAlpha;<br />	myValues[1] = kCFBooleanTrue;<br />	myKeys[2] = kCGImageDestinationLossyCompressionQuality;<br />	myValues[2] = CFNumberCreate(NULL, kCFNumberFloatType, &amp;compression);<br />	myOptions = CFDictionaryCreate( NULL, (const void **)myKeys, (const void **)myValues, 3,&amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);<br />	// Release the CFNumber and CFDictionary objects when you no longer need them.	<br /><br />	// Create a URL image destination for the given image type,<br />	// for one image, with no options.<br />	CGImageDestinationRef imageDest;<br />	imageDest=CGImageDestinationCreateWithURL(absURL,typeName, 1, myOptions);<br />	<br />	// Make sure the image destination exists before continuing.<br />	if (imageDest==nil) {<br />		goto bail;<br />	} else {<br />		puts(&quot;imageDest created&quot;);<br />	}<br />	<br />	// Add the image to the destination using previously saved options.<br />	CGImageDestinationAddImage(imageDest, image, myOptions);<br />	puts(&quot;image added&quot;);<br />	// Finalize the image destination.<br />	status = CGImageDestinationFinalize(imageDest);<br />	// Release the image as soon as you no longer need it.<br />	CGImageRelease(image);<br />	<br />bail:<br />	return status;<br />}


Et je teste avec le main suivant :


<br />#import &lt;Cocoa/Cocoa.h&gt;<br />#import &lt;Quartz/Quartz.h&gt;<br />#import &lt;QuartzCore/CoreAnimation.h&gt;	<br />#import &lt;ApplicationServices/ApplicationServices.h&gt;<br /><br />#define CGAutorelease(x) (__typeof(x))[NSMakeCollectable(x) autorelease]<br />.....<br /><br />int main (int argc, const char * argv&#91;])<br />{<br />	NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];	<br />	CGImageRef imageRef=backgroundCGImageRef(CGSizeMake(100.,200.));<br />	<br />	NSString * path=[NSHomeDirectory() stringByAppendingString:@&quot;/Desktop/newImage.jpg&quot;];<br />	NSURL * url=[NSURL URLWithString:path];<br />	<br />	CGWriteToURL( imageRef,(CFURLRef) url , kUTTypeJPEG);<br />	[pool release];<br />	return 0;<br />}<br /><br />


et j'obtiens irrémédiablement le message


% gcc pgm.m -o pgm -framework Cocoa -framework Quartz -framework QuartzCore;pgm

imageDest created
image added
..... <Error>: CGDataConsumer(url_close): write failed: -15.




Et ceci aussi avec une CGImage traduisant un fichier image
// NSImage * image=[NSImage imageNamed:@Bateaux];
// NSBitmapImageRep * bitmapImageRep=(id)[image bestRepresentationForDevice:nil] ;
// CGImageRef imageRef=[bitmapImageRep CGImage] ;
// CGImageRetain(imageRef);

Réponses

  • Philippe49Philippe49 Membre
    19:23 modifié #2
    Pas d'idée sur ce message ?



    % gcc pgm.m -o pgm -framework Cocoa -framework Quartz -framework QuartzCore;pgm

    imageDest created
    image added
    ..... <Error>: CGDataConsumer(url_close): write failed: -15.


  • 19:23 modifié #3
    dans 1200143023:

    Pas d'idée sur ce message ?



    % gcc pgm.m -o pgm -framework Cocoa -framework Quartz -framework QuartzCore;pgm

    imageDest created
    image added
    ..... <Error>: CGDataConsumer(url_close): write failed: -15.




    Dans le code d'enregistrement, t'as essayé en enlevant le "/" devant "Desktop" ? Car normalement quand tu fais stringByAppendingPathComponent il rajoute automatiquement le "/" avant.
    Enfin j'ai toujours fait [NSHomeDirectory() stringByAppendingPathComponent:@Desktop/Prout.jpg] .. après peut-être que ça changera rien  :adios!:
  • Philippe49Philippe49 Membre
    19:23 modifié #4
    dans 1200144307:

    Enfin j'ai toujours fait [NSHomeDirectory() stringByAppendingPathComponent:@Desktop/Prout.jpg] .. après peut-être que ça changera rien  :adios!:


    Je n'ose imaginer l'image que cela peut-être !!  :o

    J'essaye mais dans mon souvenir le chemin ~//Desktop est le même que /Desktop
  • 19:23 modifié #5
    Au pire essaye de nous joindre le projet, ça sera plus simple et plus rapide à  débusquer ce petit bug
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #6
    Voici le fichier pgm.m.
    A compiler sur le terminal par
    gcc pgm.m -o pgm -framework Cocoa -framework Quartz -framework QuartzCore

    et lancer par ./pgm

    Et une des docs suivies
  • 19:23 modifié #7
    dans 1200145107:

    Voici le fichier pgm.m.
    A compiler sur le terminal par
    gcc pgm.m -o pgm -framework Cocoa -framework Quartz -framework QuartzCore

    et lancer par ./pgm

    Et une des docs suivies



    Bon j'ai mis ça :
    <br />NSString * path=[NSHomeDirectory() stringByAppendingString:@&quot;Desktop/newImage.jpg&quot;];<br />	NSURL * url=[NSURL fileURLWithPath:path];<br />
    

    là  maintenant on a une vraie URL en local mais j'ai une autre erreur:

    Sat Jan 12 14:46:27 imac-de-loulou.local pgm[5018] <Error>: CGImageDestinationCreate destination parameter is nil\n

    Donc ptete que j'ai écris de la merde  ;D
  • Philippe49Philippe49 Membre
    19:23 modifié #8
    Si tu fais dans le main()
    printf ("%s",[NSHomeDirectory() UTF8String]);
    le / final n'y est pas.

    Donc le fichier n'est pas trouvé.
  • 19:23 modifié #9
    Bon ben j'ai réussi alors. J'ai rajouté en effet le "/" comme tu avais fait au départ.
    Donc tout ce que tu as a changé dans la sauvegarde c'est ça :
    <br />int main (int argc, const char * argv&#91;])<br />{<br />	NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];	<br />	CGImageRef imageRef=backgroundCGImageRef(CGSizeMake(100.,200.));<br />//	NSImage * image=[NSImage imageNamed:@&quot;Bateaux&quot;];<br />//	NSBitmapImageRep * bitmapImageRep=(id)[image bestRepresentationForDevice:nil] ;<br />//	CGImageRef imageRef=[bitmapImageRep CGImage] ;<br />//	CGImageRetain(imageRef);<br />	<br />	NSString * path=[NSHomeDirectory() stringByAppendingString:@&quot;/Desktop/newImage.jpg&quot;];<br />	NSURL * url=[NSURL fileURLWithPath:path];<br />	NSLog(@&quot;%@&quot;,url);<br />//	NSString * typeName=@&quot;jpg&quot;;<br />	<br />	//createTIFFImageFileFromCGImage(imageRef,(CFURLRef) url );<br />	CGWriteToURL( imageRef,(CFURLRef) url , kUTTypeJPEG);<br />	[pool release];<br />	return 0;<br />}<br />
    


    J'obtiens un joli point d'interrogation retourné :D
  • Philippe49Philippe49 Membre
    19:23 modifié #10
    Oui j'avais des frayeurs sur le code Core Graphics ( est-ce que le data et/ou le metadata suit correctement le processus ), et c'était juste une bévue entre URLWithString et fileURLWithPath    :crackboom:-


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