Reply To: Syphon -> CoreImage

Home Forums Syphon Syphon Development – Developer Syphon -> CoreImage Reply To: Syphon -> CoreImage

#5170
Andrea Cremaschi
Participant

Well, I am making some presence / motion analysis, using openCL (wrapped for development convenience in CIFilters), so I can’t avoid accessing pixels in CPU memory..
You pointed me in the right direction: now I can access picture data from a FBO with glReadPixels, and everything is fine again. Thanks!!

As a gift to the growing Syphon community (that will become huge!!) I can now suggest a workaround for whom may be interested in taking a bitmap snapshot of a Syphon picture (i.e. to save it to a file?) and wants to avoid messing with OpenGL.
Note that this is NOT fast at all!!

// 1. receive syphon image in a CIImage wrapper valid in openglcontext cgl_ctx
	SyphonImage *image = [[syClient newFrameImageForContext:cgl_ctx] autorelease];

	GLuint texture = [image textureName];
	NSSize imageSize = [image textureSize];

    const CGRect r = {.origin = {0, 0}, .size = {imageSize.width, imageSize.height}};
    CIImage *ciImage = [CIImage imageWithTexture:texture
											size:r.size
										 flipped:YES
									  colorSpace:cs];

// 2. create a CIContext shared with the openGL context used to create syphon image
							NSOpenGLPixelFormatAttribute	attributes[] = {
								NSOpenGLPFAPixelBuffer,
								NSOpenGLPFANoRecovery,
								NSOpenGLPFAAccelerated,
								NSOpenGLPFADepthSize, 24,
								(NSOpenGLPixelFormatAttribute) 0
							};
							NSOpenGLPixelFormat*	pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease];

							CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
							CIContext *ciCtx = [CIContext contextWithCGLContext: cgl_ctx
																	pixelFormat:[pixelFormat CGLPixelFormatObj]
																	 colorSpace:cs
																		options:nil];

// 3. create a Quartz 2d Image copy of syphon image in this last created CIContext
						CGImageRef cgImage, *imgPtr = &cgImage;

							CGLSetCurrentContext(cgl_ctx);
							*imgPtr = [ciCtx createCGImage:syphonCIImage fromRect:rect];
							glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER,
											GL_LINEAR);
							glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER,
											GL_NEAREST);

							CFRelease(cs);

							CIImage *myCGImage = [CIImage imageWithCGImage: cgImage];

// 4. finally, copy this quartz 2d image in a bitmap
						NSBitmapImageRep* bitmap=[[[NSBitmapImageRep alloc]
													   initWithBitmapDataPlanes: nil
													   pixelsWide: [syphonCIImage extent].size.width
													   pixelsHigh: [syphonCIImage extent].size.height
													   bitsPerSample:8
													   samplesPerPixel:4
													   hasAlpha: YES
													   isPlanar: NO
													   colorSpaceName: NSCalibratedRGBColorSpace
													   bytesPerRow: 0
													   bitsPerPixel:32] autorelease] ;

							NSGraphicsContext * context = [NSGraphicsContext
														   graphicsContextWithBitmapImageRep: bitmap] ;

							CGRect rect  = [syphonCIImage extent];							

							[[context CIContext] drawImage: myCGImage
												   atPoint: CGPointZero
												  fromRect: rect];