Page 1 of 1

Image filters (Cocoa CIKernel example)

Posted: Thu Oct 18, 2012 4:31 pm
by wilbert
Maybe others like to play with the kernel language as well and post other examples.

Information about the kernel language :
https://developer.apple.com/library/mac ... ction.html

CoreImageKernel.pbi

Code: Select all

Global NewMap CoreImageKernel.i()

Procedure AddCoreImageKernels(KernelCode.s)
  Protected.i Kernels, Kernel, Enum
  Protected.s KernelName
  Kernels = CocoaMessage(0, 0, "CIKernel kernelsWithString:$", @KernelCode)
  If Kernels
    Enum = CocoaMessage(0, Kernels, "objectEnumerator")
    Kernel = CocoaMessage(0, Enum, "nextObject")
    While Kernel
      KernelName = PeekS(CocoaMessage(0, CocoaMessage(0, Kernel, "name"), "UTF8String"), -1, #PB_UTF8)
      CoreImageKernel(KernelName) = CocoaMessage(0, Kernel, "retain")
      Kernel = CocoaMessage(0, Enum, "nextObject")
    Wend
  EndIf
EndProcedure

Procedure ApplyCoreImageKernel(Image, KernelName.s, Arguments = #nil)
  Protected Kernel = CoreImageKernel(KernelName)
  If Kernel And IsImage(Image)
    
    Protected CIImage, Rep = CocoaMessage(0, CocoaMessage(0, ImageID(Image), "representations"), "objectAtIndex:", 0)
    If CocoaMessage(0, Rep, "isKindOfClass:", CocoaMessage(0, 0, "NSBitmapImageRep class"))
      CIImage = CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "CIImage alloc"), "initWithBitmapImageRep:", Rep), "autorelease")
    Else
      CIImage = CocoaMessage(0, 0, "CIImage imageWithData:", CocoaMessage(0, ImageID(Image), "TIFFRepresentation"))
    EndIf
    
    Protected Filter = CocoaMessage(0, CocoaMessage(0, 0, "CIFilter new"), "autorelease")
    Protected ArgArr = CocoaMessage(0, 0, "NSArray arrayWithObject:", CocoaMessage(0, 0, "CISampler samplerWithImage:", CIImage))
    If Arguments : CocoaMessage(@ArgArr, ArgArr, "arrayByAddingObjectsFromArray:", Arguments) : EndIf
    CocoaMessage(@CIImage, Filter, "apply:", Kernel, "arguments:", ArgArr, "options:", #nil)
    
    Protected ImageRect.NSRect\size\width = ImageWidth(Image) : imageRect\size\height = ImageHeight(Image)
    Protected Delta.CGFloat = 1
    StartDrawing(ImageOutput(Image))
    CocoaMessage(0, CIImage, "drawInRect:@", @ImageRect, "fromRect:@", @ImageRect, "operation:", #NSCompositeCopy, "fraction:@", @Delta)
    StopDrawing()
    
  EndIf
EndProcedure

Re: Image filters (Cocoa CIKernel example)

Posted: Thu Oct 18, 2012 4:33 pm
by wilbert
Simple test example with one kernel with one additional argument (you can use more kernels if you want).
If you create a kernel that requires additional arguments next to sampler src (the source image), you need to pass them as an NSArray or NSMutableArray.

Code: Select all

XIncludeFile "CoreImageKernel.pbi"

UsePNGImageDecoder()

Define KernelArgs = CocoaMessage(0, CocoaMessage(0, 0, "NSMutableArray alloc"), "initWithCapacity:", 1)
Define KernelCode.s

KernelCode + "kernel vec4 test(sampler src, float k)"
KernelCode + "{"
KernelCode + "  vec4 s;"
KernelCode + "  s = sample(src, samplerCoord(src));"
KernelCode + "  s.rgb = s.rgb + k * s.a;"
KernelCode + "  return s;"
KernelCode + "}"

AddCoreImageKernels(KernelCode)


If OpenWindow(0, 0, 0, 180, 100, "CIKernel example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  If LoadImage(0, #PB_Compiler_Home + "Examples/3D/Data/Textures/Caisse.png")
    
    Define Value.f = 0.5
    CocoaMessage(0, KernelArgs, "removeAllObjects")
    CocoaMessage(0, KernelArgs, "addObject:", CocoaMessage(0, 0, "NSNumber numberWithFloat:@", @Value))
    
    ApplyCoreImageKernel(0, "test", KernelArgs)
    
    ImageGadget(0,  10, 10, 64, 64, ImageID(0))
    
  EndIf
  
  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf
Scanlines effect

Code: Select all

XIncludeFile "CoreImageKernel.pbi"

UsePNGImageDecoder()

Define KernelArgs = CocoaMessage(0, CocoaMessage(0, 0, "NSMutableArray alloc"), "initWithCapacity:", 1)
Define KernelCode.s

KernelCode + "kernel vec4 scanlines(sampler src)"
KernelCode + "{"
KernelCode + "  vec4 s = sample(src, destCoord());"
KernelCode + "  s.rgb *= mod(destCoord().y, 2.0);"
KernelCode + "  return s;"
KernelCode + "}"

AddCoreImageKernels(KernelCode)


If OpenWindow(0, 0, 0, 500, 600, "CIKernel example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  If LoadImage(0, #PB_Compiler_Home + "Examples/3D/Data/Textures/Caisse.png")
    
    ApplyCoreImageKernel(0, "scanlines")
    
    ImageGadget(0,  10, 10, 357, 492, ImageID(0))
    
  EndIf
  
  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf