public static NSImage Tint(this NSImage image, NSColor tint) { CIFilter colorGenerator = CIFilter.FromName("CIConstantColorGenerator"); CIColor color = CIColor.FromCGColor(tint.ToCG()); colorGenerator.SetValueForKey(color, CIFilterInputKey.Color); CIFilter colorFilter = CIFilter.FromName("CIColorControls"); colorFilter.SetValueForKey(colorGenerator.ValueForKey(CIFilterOutputKey.Image), CIFilterInputKey.Image); colorFilter.SetValueForKey(NSNumber.FromFloat(3f), CIFilterInputKey.Saturation); colorFilter.SetValueForKey(NSNumber.FromFloat(0.35f), CIFilterInputKey.Brightness); colorFilter.SetValueForKey(NSNumber.FromFloat(1f), CIFilterInputKey.Contrast); CIFilter monochromeFilter = CIFilter.FromName("CIColorMonochrome"); CIImage baseImage = CIImage.FromCGImage(image.CGImage); monochromeFilter.SetValueForKey(baseImage, CIFilterInputKey.Image); monochromeFilter.SetValueForKey(CIColor.FromRgb(0.75f, 0.75f, 0.75f), CIFilterInputKey.Color); monochromeFilter.SetValueForKey(NSNumber.FromFloat(1f), CIFilterInputKey.Intensity); CIFilter compositingFilter = CIFilter.FromName("CIMultiplyCompositing"); compositingFilter.SetValueForKey(colorFilter.ValueForKey(CIFilterOutputKey.Image), CIFilterInputKey.Image); compositingFilter.SetValueForKey(monochromeFilter.ValueForKey(CIFilterOutputKey.Image), CIFilterInputKey.BackgroundImage); CIImage outputImage = (CIImage)compositingFilter.ValueForKey(CIFilterOutputKey.Image); var extent = outputImage.Extent; var newsize = sd.Size.Truncate(extent.Size); var tintedImage = new NSImage(newsize); var newrep = new NSBitmapImageRep(IntPtr.Zero, newsize.Width, newsize.Height, 8, 4, true, false, NSColorSpace.DeviceRGB, 4 * newsize.Width, 32); tintedImage.AddRepresentation(newrep); var graphics = NSGraphicsContext.FromBitmap(newrep); NSGraphicsContext.GlobalSaveGraphicsState(); NSGraphicsContext.CurrentContext = graphics; var ciContext = CIContext.FromContext(graphics.GraphicsPort, new CIContextOptions { UseSoftwareRenderer = true }); ciContext.DrawImage(outputImage, extent, extent); NSGraphicsContext.GlobalRestoreGraphicsState(); newrep.Size = image.Size; return(tintedImage); }
// On load, construct the CIRawFilter public override void ViewDidLoad() { base.ViewDidLoad(); var asset = Asset; if (asset == null) { return; } // Setup options to request original image. var options = new PHImageRequestOptions { Version = PHImageRequestOptionsVersion.Original, Synchronous = true }; // Request the image data and UTI type for the image. PHImageManager.DefaultManager.RequestImageData(asset, options, (imageData, dataUTI, _, __) => { if (imageData == null || dataUTI == null) { return; } // Create a CIRawFilter from original image data. // UTI type is passed in to provide the CIRawFilter with a hint about the UTI type of the Raw file. //var rawOptions = [String (kCGImageSourceTypeIdentifierHint) : dataUTI ] var rawOptions = new NSMutableDictionary(); var imageIOLibrary = Dlfcn.dlopen("/System/Library/Frameworks/ImageIO.framework/ImageIO", 0); var key = Dlfcn.GetIntPtr(imageIOLibrary, "kCGImageSourceTypeIdentifierHint"); rawOptions.LowlevelSetObject(dataUTI, key); ciRawFilter = CIFilter.CreateRawFilter(imageData, rawOptions); if (ciRawFilter == null) { return; } // Get the native size of the image produced by the CIRawFilter. var sizeValue = ciRawFilter.ValueForKey(Keys.kCIOutputNativeSizeKey) as CIVector; if (sizeValue != null) { imageNativeSize = new CGSize(sizeValue.X, sizeValue.Y); } // Record the original value of the temperature, and setup the editing slider. var tempValue = (NSNumber)ciRawFilter.ValueForKey(Keys.kCIInputNeutralTemperatureKey); if (tempValue != null) { originalTemp = tempValue.FloatValue; TempSlider.SetValue(tempValue.FloatValue, animated: false); } // Record the original value of the tint, and setup the editing slider. var tintValue = (NSNumber)ciRawFilter.ValueForKey(Keys.kCIInputNeutralTintKey); if (tintValue != null) { originalTint = tintValue.FloatValue; TintSlider.SetValue(tintValue.FloatValue, animated: false); } }); // Create EAGL context used to render the CIImage produced by the CIRawFilter to display. ImageView.Context = new EAGLContext(EAGLRenderingAPI.OpenGLES3); ciContext = CIContext.FromContext(ImageView.Context, new CIContextOptions { CIImageFormat = CIImage.FormatRGBAh }); }
// On load, construct the CIRawFilter public override void ViewDidLoad () { base.ViewDidLoad (); var asset = Asset; if (asset == null) return; // Setup options to request original image. var options = new PHImageRequestOptions { Version = PHImageRequestOptionsVersion.Original, Synchronous = true }; // Request the image data and UTI type for the image. PHImageManager.DefaultManager.RequestImageData (asset, options, (imageData, dataUTI, _, __) => { if (imageData == null || dataUTI == null) return; // Create a CIRawFilter from original image data. // UTI type is passed in to provide the CIRawFilter with a hint about the UTI type of the Raw file. //var rawOptions = [String (kCGImageSourceTypeIdentifierHint) : dataUTI ] var rawOptions = new NSMutableDictionary (); var imageIOLibrary = Dlfcn.dlopen ("/System/Library/Frameworks/ImageIO.framework/ImageIO", 0); var key = Dlfcn.GetIntPtr (imageIOLibrary, "kCGImageSourceTypeIdentifierHint"); rawOptions.LowlevelSetObject (dataUTI, key); ciRawFilter = CIFilter.CreateRawFilter (imageData, rawOptions); if (ciRawFilter == null) return; // Get the native size of the image produced by the CIRawFilter. var sizeValue = ciRawFilter.ValueForKey (Keys.kCIOutputNativeSizeKey) as CIVector; if (sizeValue != null) imageNativeSize = new CGSize (sizeValue.X, sizeValue.Y); // Record the original value of the temperature, and setup the editing slider. var tempValue = (NSNumber)ciRawFilter.ValueForKey (Keys.kCIInputNeutralTemperatureKey); if (tempValue != null) { originalTemp = tempValue.FloatValue; TempSlider.SetValue (tempValue.FloatValue, animated: false); } // Record the original value of the tint, and setup the editing slider. var tintValue = (NSNumber)ciRawFilter.ValueForKey (Keys.kCIInputNeutralTintKey); if (tintValue != null) { originalTint = tintValue.FloatValue; TintSlider.SetValue (tintValue.FloatValue, animated: false); } }); // Create EAGL context used to render the CIImage produced by the CIRawFilter to display. ImageView.Context = new EAGLContext (EAGLRenderingAPI.OpenGLES3); ciContext = CIContext.FromContext (ImageView.Context, new CIContextOptions { CIImageFormat = CIImage.FormatRGBAh }); }