CIHazeFilterSample

A PyObjC Example without documentation

Sources

HazeFilterView.py

import Cocoa
import MyHazeFilter
import objc
import Quartz


class HazeFilterView(Cocoa.NSView):
    filter = objc.ivar()  # noqa: A003
    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 Cocoa
import objc
import Quartz
from objc import super  # noqa: A004

_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):
        return cls.alloc().init()

    def init(self):
        global _hazeRemovalKernel

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

        return super().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

import HazeFilterView  # noqa: F401
import MyHazeFilter  # noqa: F401
from PyObjCTools import AppHelper

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"],
)