Thursday, August 13, 2020

#1 2020-05-22 03:31:45 pm

Fredrik71
Member
Registered: 2019-10-23
Posts: 333

CIFilter, with reference code...

Today I discover this site that use CIFilter and I thought this should be possible in ASObjC.
And maybe its only possible to do 1 filter per image if not a filter kernel are used.

If I understand the basic layout in ASObjC maybe it would be so much easier to make other
filters to use ASObjC.

https://noahgilmore.com/blog/cifilterio/
https://cifilter.io/

The reference for my example
https://cifilter.io/CIBokehBlur/
https://developer.apple.com/documentati … guage=objc
https://developer.apple.com/documentati … on_filters
https://developer.apple.com/documentati … blurfilter

I find Shanes code that use CIQRCodeGenerator and from that I could come closer to something
that works. So I start to edit his code... or at least try to understand it more. There is some
code I have not touch from Shanes.

This code is not complete in any form... so I need some help.

Applescript:

use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
use scripting additions

set theImage to POSIX path of (choose file)
set thisImageString to current application's NSString's stringWithString:theImage

-- CIFilter Protocol
set theImageFilter to current application's CIFilter's filterWithName:"CIBokenhBlur"
set thisData to theImageFilter's setValue:thisImageString forKey:"inputImage" --> Image
theImageFilter's setValue:"30" forKey:"inputRadius" --> Distance: min 0 max 500
theImageFilter's setValue:"1" forKey:"inoutRingAmount" --> Scalar: min 0 max 1
theImageFilter's setValue:"7" forKey:"inputRingSize" --> Scalar: min 0
theImageFilter's setValue:"0" forKey:"inputSoftness" --> Scalar: min 0 max 10

set baseImage to theImageFilter's outputImage()

-- make image rep
set imageRep to current application's NSBitmapImageRep's alloc()'s initWithCIImage:baseImage
set actualWidth to imageRep's |size|()'s width()
set actualHeight to imageRep's |size|()'s height()
set theScale to theWidth / actualWidth

-- restore state and save from new rep
current application's NSGraphicsContext's restoreGraphicsState()
set theProps to current application's NSDictionary's dictionaryWithObject:1.0 forKey:(current application's NSImageCompressionFactor)
set imageData to (newRep's representationUsingType:(current application's NSTIFFFileType) |properties|:theProps)
(imageData's writeToFile:posixPath atomically:true)

Regards.

Last edited by Fredrik71 (2020-05-22 03:48:55 pm)


The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

 

#2 2020-05-22 06:43:53 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6440

Re: CIFilter, with reference code...

It's not clear what you're trying to do, but this uses some of your code and then applies another filter to scale the image.

Applescript:

use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
use scripting additions

set theImage to (choose file)
set outPath to POSIX path of ((path to desktop as text) & "Test.tif")

set theCIImage to current application's CIImage's imageWithContentsOfURL:theImage

-- CIFilter Protocol
set theImageFilter to current application's CIFilter's filterWithName:"CIBokehBlur"
theImageFilter's setValue:theCIImage forKey:(current application's kCIInputImageKey)
theImageFilter's setValue:30 forKey:"inputRadius" --> Distance: min 0 max 500
theImageFilter's setValue:1 forKey:"inputRingAmount" --> Scalar: min 0 max 1
theImageFilter's setValue:7 forKey:"inputRingSize" --> Scalar: min 0
theImageFilter's setValue:0 forKey:"inputSoftness" --> Scalar: min 0 max 10
set theCIImage to theImageFilter's valueForKey:(current application's kCIOutputImageKey)

-- get the rectangle containing the image
set {{x, y}, {oldWidth, oldHeight}} to theCIImage's extent()
-- define the new size
set theWidth to 500 -- points
set theScale to theWidth / oldWidth

set theCIFilter to (current application's CIFilter's filterWithName:"CILanczosScaleTransform" withInputParameters:{inputScale:theScale, inputImage:theCIImage})
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))

-- make image rep and save tiff
set imageRep to current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage
set imageData to imageRep's TIFFRepresentation()
imageData's writeToFile:outPath atomically:true


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#3 2020-05-22 10:26:19 pm

Fredrik71
Member
Registered: 2019-10-23
Posts: 333

Re: CIFilter, with reference code...

Aha...let me explain, doing search on google for CIFilter I find a site that use it on iOS app.
So the idea was... open image, apply CIFilter on the image, store the result in new image.

In other words, doing something like this.
https://developer.apple.com/documentati … in_filters

The example above from Apple apply 3 different filter to the same image.

I guess if the code is converted to applet it would be possible to make interface-displayable
UIImage and assigning the UIImage to a UIImageView in the view hierarchy. To be able
to see the result in realtime. But that is so far away what my knowledge in coding are. smile

Wonderful Shane, now the fun part... doing other filter with your reference... thanks.

The core ASObjC could be a handler for different CIFilter with input values.

Regards.


The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

 

#4 2020-05-22 10:39:39 pm

Fredrik71
Member
Registered: 2019-10-23
Posts: 333

Re: CIFilter, with reference code...

Shane, with your reference code I use CISepiaTone.
And the only thing I did was to change the CIFilers Protocol.

This is so cool, thanks again Shane.

Applescript:

use framework "Foundation"
use framework "AppKit"
use framework "CoreImage"
use scripting additions

set theImage to (choose file)
set outPath to POSIX path of ((path to desktop as text) & "Test.tif")

set theCIImage to current application's CIImage's imageWithContentsOfURL:theImage

-- CIFilter Protocol
set theImageFilter to current application's CIFilter's filterWithName:"CISepiaTone"
theImageFilter's setValue:theCIImage forKey:(current application's kCIInputImageKey)
theImageFilter's setValue:0.3 forKey:"inputIntensity"
set theCIImage to theImageFilter's valueForKey:(current application's kCIOutputImageKey)

-- get the rectangle containing the image
set {{x, y}, {oldWidth, oldHeight}} to theCIImage's extent()
-- define the new size
set theWidth to 680 -- points
set theScale to theWidth / oldWidth

set theCIFilter to (current application's CIFilter's filterWithName:"CILanczosScaleTransform" withInputParameters:{inputScale:theScale, inputImage:theCIImage})
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))

-- make image rep and save tiff
set imageRep to current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage
set imageData to imageRep's TIFFRepresentation()
imageData's writeToFile:outPath atomically:true


The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

 

#5 2020-05-22 10:39:48 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6440

Re: CIFilter, with reference code...

UIImage is iOS-only. NSImages is the (not exactly) equivalent in macOS.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#6 2020-05-22 11:54:35 pm

Fredrik71
Member
Registered: 2019-10-23
Posts: 333

Re: CIFilter, with reference code...

Made some quick handlers of your code if someone else like to build a library of CIFilters.

Sometimes its not clear how to convert Objective-C code to ASObjC but with your help
I learn so much so thank you, and I agree the Bridge TV Show from Sweden is great... wink

But now I read this. smile
https://developer.apple.com/documentati … meter_keys

Applescript:

-- CIFilters Handlers

-- CIFilter SepiaTone Protocol
on ciFilterSepiaTone(inputImageData, inputIntensityValue)
   set theImageFilter to current application's CIFilter's filterWithName:"CISepiaTone"
   theImageFilter's setValue:inputImageData forKey:(current application's kCIInputImageKey)
   theImageFilter's setValue:inputIntensityValue forKey:"inputIntensity" --> range:(0.0 - 1.0)
   set theCIImage to theImageFilter's valueForKey:(current application's kCIOutputImageKey)
end ciFilterSepiaTone

-- CIFilter LanczosScaleTransform Protocol
on ciFilterLanczosScaleTransform(inputImageData, inputScaleValue)
   set theCIFilter to (current application's CIFilter's filterWithName:"CILanczosScaleTransform" withInputParameters:{inputScale:inputScaleValue, inputImage:inputImageData})
   set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
end ciFilterLanczosScaleTransform

-- Image format TIFF
on saveImageDataToTiff(inputData, outPath)
   set imageRep to current application's NSBitmapImageRep's alloc()'s initWithCIImage:inputData
   set imageData to imageRep's TIFFRepresentation()
   imageData's writeToFile:outPath atomically:true
end saveImageDataToTiff


The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

 

#7 2020-05-26 01:23:37 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 333

Re: CIFilter, with reference code...

Shane do you know how CIVector works?, I need the imageCenter of x, y

the code I find in cocoa is...

[CIVector vectorWithX: filterCenter.x Y: filterCenter.y]



So I'm guessing the CIVector is a list

Here is the handler that use inputCenterValue

Applescript:

-- CIFilter Pixellate Protocol
on ciFilterPixellate(inputImageData, inputCenterValue, inputScaleValue)
   set theImageFilter to current application's CIFilter's filterWithName:"CIPixellate"
   theImageFilter's setValue:inputImageData forKey:(current application's kCIInputImageKey)
   theImageFilter's setValue:inputCenterValue forKey:"inputCenter"
   theImageFilter's setValue:inputScaleValue forKey:"inputScale"
   ##### Default value #############
   -- theImageFilter's setDefaults()
   #################################
   set theCIImage to theImageFilter's valueForKey:(current application's kCIOutputImageKey)
end ciFilterPixellate


The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

 

#8 2020-05-26 02:00:33 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6440

Re: CIFilter, with reference code...

Fredrik71 wrote:

So I'm guessing the CIVector is a list



No, it's a class in its own right. So:

Applescript:

set theVec to current application's CIVector's vectorWithX:10.5 Y:5.5 -- or whatever values suit

and then:

Applescript:

theImageFilter's setValue:theVec forKey:"inputCenter"


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#9 2020-05-26 02:58:35 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 333

Re: CIFilter, with reference code...

Thanks, Shane...

I was very close to solve it myself with code similar to yours, but I got some errors...

Here is the results of the Pixellate Filter

Applescript:

use framework "Foundation"
use framework "AppKit" --> NSBitmapImageRep
use framework "CoreImage" --> CIImage
use scripting additions

property theImageWidth : 1024 -- points

set theImage to (choose file)
set outPath to POSIX path of ((path to desktop as text) & "Test1.tif")

set theCIImage to current application's CIImage's imageWithContentsOfURL:theImage

-- Set the imageCenter for Pixellate filter.
set theCenter to current application's CIVector's vectorWithX:150 Y:150
set theCIImage to my ciFilterPixellate(theCIImage, theCenter, 8)

-- get the rectangle containing the image
set {{x, Y}, {oldWidth, oldHeight}} to theCIImage's extent()
-- define the new size
set theWidth to theImageWidth -- points
set theScale to theWidth / oldWidth

-- Set the Scale of the image
set theCIImage to my ciFilterLanczosScaleTransform(theCIImage, theScale)

-- Save the Image to TIFF
saveImageDataToTiff(theCIImage, outPath)

-- CIFilter Pixellate Protocol
on ciFilterPixellate(inputImageData, inputCenterValue, inputScaleValue)
   set theImageFilter to current application's CIFilter's filterWithName:"CIPixellate"
   theImageFilter's setValue:inputImageData forKey:(current application's kCIInputImageKey)
   theImageFilter's setValue:inputCenterValue forKey:"inputCenter"
   theImageFilter's setValue:inputScaleValue forKey:"inputScale"
   ##### Default value #############
   -- theImageFilter's setDefaults()
   #################################
   set theCIImage to theImageFilter's valueForKey:(current application's kCIOutputImageKey)
end ciFilterPixellate

-- CIFilter LanczosScaleTransform Protocol
on ciFilterLanczosScaleTransform(inputImageData, inputScaleValue)
   set theCIFilter to (current application's CIFilter's filterWithName:"CILanczosScaleTransform" withInputParameters:{inputScale:inputScaleValue, inputImage:inputImageData})
   set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
end ciFilterLanczosScaleTransform

-- Image format TIFF
-- https://developer.apple.com/documentation/appkit/nsbitmapimagerep/1395587-initwithciimage?language=objc
on saveImageDataToTiff(inputData, outPath)
   set imageRep to current application's NSBitmapImageRep's alloc()'s initWithCIImage:inputData
   set imageData to imageRep's TIFFRepresentation()
   imageData's writeToFile:outPath atomically:true
end saveImageDataToTiff


The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

 

#10 2020-05-26 03:07:02 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 333

Re: CIFilter, with reference code...

Applescript:

-- CIFilter Pixellate Protocol
on ciFilterPixellate(inputImageData, inputCenterX, inputCenterY, inputScaleValue)
   set theImageFilter to current application's CIFilter's filterWithName:"CIPixellate"
   set theImageCenter to current application's CIVector's vectorWithX:inputCenterX Y:inputCenterY
   theImageFilter's setValue:inputImageData forKey:(current application's kCIInputImageKey)
   theImageFilter's setValue:theImageCenter forKey:"inputCenter"
   theImageFilter's setValue:inputScaleValue forKey:"inputScale"
   ##### Default value #############
   -- theImageFilter's setDefaults()
   #################################
   set theCIImage to theImageFilter's valueForKey:(current application's kCIOutputImageKey)
end ciFilterPixellate


The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)