CIHazeFilterSample

Translation into python of and ADC example of the same name.

Sources

HazeFilterView.py

import objc
import Quartz
import Cocoa

import MyHazeFilter

class HazeFilterView (Cocoa.NSView):
    filter = objc.ivar()
    distance = objc.ivar(type=objc._C_FLT)
    slope = objc.ivar(type=objc._C_FLT)

    def distanceSliderChanged_(self, sender):
        self.distance = sender.floatValue()
        self.setNeedsDisplay_(True)

    def slopeSliderChanged_(self, sender):
        self.slope = sender.floatValue()
        self.setNeedsDisplay_(True)

    def drawRect_(self, rect):
        cg = Quartz.CGRectMake(
                Cocoa.NSMinX(rect), Cocoa.NSMinY(rect), Cocoa.NSWidth(rect), Cocoa.NSHeight(rect))

        context = Cocoa.NSGraphicsContext.currentContext().CIContext()

        if self.filter is None:
            # make sure initialize is called
            MyHazeFilter.MyHazeFilter.pyobjc_classMethods.class__()

            url = Cocoa.NSURL.fileURLWithPath_(
                Cocoa.NSBundle.mainBundle().pathForResource_ofType_(
                    "CraterLake", "jpg"))
            self.filter = Quartz.CIFilter.filterWithName_("MyHazeRemover")
            self.filter.setValue_forKey_(
                Quartz.CIImage.imageWithContentsOfURL_(url),
                "inputImage")

            self.filter.setValue_forKey_(
                Quartz.CIColor.colorWithRed_green_blue_(0.7, 0.9,  1),
                "inputColor")

        self.filter.setValue_forKey_(self.distance, "inputDistance")
        self.filter.setValue_forKey_(self.slope, "inputSlope")

        if context is not None:
            context.drawImage_atPoint_fromRect_(
                    self.filter.valueForKey_("outputImage"),
                    cg.origin, cg)

MyHazeFilter.py

import objc
from objc import super
import Cocoa
import Quartz

_hazeRemovalKernel = None

class MyHazeFilter (Quartz.CIFilter):
    inputImage      = objc.ivar()
    inputColor      = objc.ivar()
    inputDistance   = objc.ivar()
    inputSlope      = objc.ivar()


    @classmethod
    def initialize(cls):
        Quartz.CIFilter.registerFilterName_constructor_classAttributes_(
                "MyHazeRemover",  cls, {
                    Quartz.kCIAttributeFilterDisplayName: "Haze Remover" ,
                    Quartz.kCIAttributeFilterCategories: [
                        Quartz.kCICategoryColorAdjustment, Quartz.kCICategoryVideo,
                        Quartz.kCICategoryStillImage, Quartz.kCICategoryInterlaced,
                        Quartz.kCICategoryNonSquarePixels,
                    ],
                    "inputDistance": {
                        Quartz.kCIAttributeMin: 0.0,
                        Quartz.kCIAttributeMax: 1.0,
                        Quartz.kCIAttributeSliderMin: 0.0,
                        Quartz.kCIAttributeSliderMax: 0.7,
                        Quartz.kCIAttributeDefault: 0.2,
                        Quartz.kCIAttributeIdentity: 0.0,
                        Quartz.kCIAttributeType: Quartz.kCIAttributeTypeScalar,
                    },

                    "inputSlope": {
                        Quartz.kCIAttributeSliderMin: -0.01,
                        Quartz.kCIAttributeSliderMax: 0.01,
                        Quartz.kCIAttributeDefault: 0.0,
                        Quartz.kCIAttributeIdentity: 0.0,
                        Quartz.kCIAttributeType: Quartz.kCIAttributeTypeScalar,
                    },

                    "inputColor": {
                        Quartz.kCIAttributeDefault: Quartz.CIColor.colorWithRed_green_blue_alpha_(
                            1.0, 1.0, 1.0, 1.0),
                    },
                })

    @classmethod
    def filterWithName_(cls, name):
        filter = cls.alloc().init()
        return filter

    def init(self):
        global _hazeRemovalKernel

        if _hazeRemovalKernel is None:
            bundle = Cocoa.NSBundle.bundleForClass_(type(self))
            with open(bundle.pathForResource_ofType_(
                "MyHazeRemoval", "cikernel"), 'r') as fp:
                code = fp.read()
            kernels = Quartz.CIKernel.kernelsWithString_(code)
            _hazeRemovalKernel = kernels[0]

        return super(MyHazeFilter, self).init()

    def outputImage(self):
        src = Quartz.CISampler.samplerWithImage_(self.inputImage)

        return self.apply_arguments_options_(_hazeRemovalKernel,
                (src, self.inputColor, self.inputDistance, self.inputSlope),
                { "definition": src.definition() })

main.py

from PyObjCTools import  AppHelper

import HazeFilterView
import MyHazeFilter

import objc; objc.setVerbose(True)

AppHelper.runEventLoop()

setup.py

"""
Script for building the example.

Usage:
    python3 setup.py py2app
"""
from setuptools import setup

setup(
    name="CIHazeFilterSample",
    app=["main.py"],
    data_files=[
        "English.lproj",
        "MyHazeRemoval.cikernel",
        "CraterLake.jpg"
    ],
    setup_requires=[
        "py2app",
        "pyobjc-framework-Cocoa",
        "pyobjc-framework-Quartz",
    ]
)

Resources