Swift Image Filter - image

The filtering on the photo works but I'm stuck with this problem.
When I run this code:
let originalImage = CIImage(image: imageView.image)
var filter = CIFilter(name: "CIPhotoEffectMono")
filter.setDefaults()
filter.setValue(originalImage, forKey: kCIInputImageKey)
var newImage = UIImage(CIImage: filter.outputImage)
imageView.image = newImage
The first error is:
BSXPCMessage received error for message: Connection interrupted
The second error is:
fatal error: unexpectedly found nil while unwrapping an Optional value
Then the app crashes.
How would I fix it and the errors?

Try this:
let originalImage = CIImage(image: imageView.image)
var filter = CIFilter(name: "CIPhotoEffectMono")
filter.setValue(originalImage, forKey: kCIInputImageKey)
let context = CIContext(options:nil)
let ouputImage = context.createdCGImage(filter,fromRect:filter.extend())
var newImage = UIImage(CGImage: ouputImage)
imageView.image = newImage

Your code runs fine. Your image source imageView.image is probably nil when you call it. You can try this at playground:
let myPicture = UIImage(data: NSData(contentsOfURL: NSURL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!)!)!
let filter = CIFilter(name: "CIPhotoEffectMono")
filter.setValue(CIImage(image: myPicture), forKey: kCIInputImageKey)
let newImage = UIImage(CIImage: filter.outputImage)

I Found A Solution:
Updated
let originalImage = CIImage(image: imageView.image)
var filter = CIFilter(name: "CIPhotoEffectMono")
filter.setValue(originalImage, forKey: kCIInputImageKey)
let context = CIContext(options: [kCIContextUseSoftwareRenderer: true])
let outputImage = context.createCGImage(filter.outputImage, fromRect: filter.outputImage.extent())
var newImage = UIImage(CGImage: outputImage)
imageView.image = newImage
*Based on Lamar's code.
CIContext(options: nil) was causing BSXPCMessage received error for message: Connection interrupted error.
SO replace:
CIContext(options: nil) with CIContext(options: [kCIContextUseSoftwareRenderer: true])
Thanks For The Help:
Lamar
The app doesn't crash anymore.

**I have added Black n White Effect To an Image**
UIGraphicsBeginImageContext(clickedImage.bounds.size)
clickedImage.layer.renderInContext(UIGraphicsGetCurrentContext())
var image2: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
origionalimage=image2;
var CIfilterName = "CIPhotoEffectTonal"
let ciContext = CIContext(options: nil)
let startImage = CIImage(image: image2)
let filter = CIFilter(name: CIfilterName)
filter.setDefaults()
filter.setValue(startImage, forKey: kCIInputImageKey)
let filteredImageData = filter.valueForKey(kCIOutputImageKey) as! CIImage
let filteredImageRef = ciContext.createCGImage(filteredImageData, fromRect: filteredImageData.extent())
var newImage = UIImage(CGImage: filteredImageRef)!
self.mediaData = UIImagePNGRepresentation(newImage )
self.videoThumbData = UIImageJPEGRepresentation(image2, 0.1)
self.clickedImage.image = newImage;

Related

Converting from UIImage to a SwiftUI Image results in a blank image of the same size

I am trying to convert a UIImage to a SwiftUI Image using the init(uiImage:) initializer. My UIImage itself is created from a CIImage generated by a CIQRCodeGenerator CIFilter. I am running my code on a Playground in Xcode 11.1 GM seed 1. Here is the entirety of my code:
import SwiftUI
import UIKit
func qrCodeImage(for string: String) -> Image? {
let data = string.data(using: String.Encoding.utf8)
guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
qrFilter.setValue(data, forKey: "inputMessage")
guard let ciImage = qrFilter.outputImage else { return nil }
let uiImage = UIImage(ciImage: ciImage)
let image = Image(uiImage: uiImage)
return image
}
let image = qrCodeImage(for: "fdsa")
And here is the result:
Even when I transform the image with CGAffineTransform(scaleX: 10, y: 10), the resulting SwiftUI Image at the end is still the same size, but blank.
Following solution provided in: Generating QR Code with SwiftUI shows empty picture
Here is the code:
var ciContext = CIContext()
func qrCodeImage(for string: String) -> Image? {
let data = string.data(using: String.Encoding.utf8)
guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
qrFilter.setValue(data, forKey: "inputMessage")
guard let ciImage = qrFilter.outputImage else { return nil }
let cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent)
let uiImage = UIImage(cgImage: cgImage!)
let image = Image(uiImage: uiImage)
return image
}
let image = qrCodeImage(for: "fdsa")
Result:
screenshot in swift playground
Can confirm I encounter the same issue with a SwiftUI Image using a UIImage initialized from data. Can verify that the image is loaded when paused in debugging, but it does not display in the SwiftUI Image.
This solution worked for me: explicitly specify the image rendering mode. In my case I added the following: .renderingMode(.original)
#Eugene remark worked for me:
let image = Image(uiImage: uiImage).renderingMode(.original)

how to get UrlPath and name of images in the array in swift 3?

I have an array of images that selected from gallery in the swift 3
I used method below for get these images url path and names but It doesn't work for me
I read this
How to get the image or movie path from the photo Library in swift
but the problem is that I stored images in the array and want to get url path and names from this array
here is the codes
let imageURL = init[UIImagePickerControllerReferenceURL] as NSURL
let imageName = imageURL.path!.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let localPath = documentDirectory.stringByAppendingPathComponent(imageName)
let image = info[UIImagePickerControllerOriginalImage] as UIImage
let data = UIImagePNGRepresentation(image)
data.writeToFile(localPath, atomically: true)
let imageData = NSData(contentsOfFile: localPath)!
let photoURL = NSURL(fileURLWithPath: localPath)
let imageWithData = UIImage(data: imageData)!
For Swift 3 try this code.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL
let imageName = imageUrl?.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
if !FileManager.default.fileExists(atPath: localPath!.path) {
do {
try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
print("file saved")
}catch {
print("error saving file")
}
}
else {
print("file already exists")
}
}

Convert UIimage (take a picture) to NSData

I used this method to take a picture.
func convertImageFromCMSampleBufferRef(sampleBuffer:CMSampleBuffer) -> CIImage{
let pixelBuffer:CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)!;
let ciImage:CIImage = CIImage(CVPixelBuffer: pixelBuffer)
if done == true {
newImage = UIImage(CIImage:ciImage, scale: CGFloat(1.0), orientation: .DownMirrored)
var imageData = UIImageJPEGRepresentation(newImage, 0.6)
var compressedJPGImage = UIImage(data: imageData)
UIImageWriteToSavedPhotosAlbum(compressedJPGImage!, nil, nil, nil)
}
return ciImage;
}
The code should work, but the variable imageData = nil
I tried converting the image in PNG, but with the same result.
with print
newImage = , {720, 1280} imageData = nil
You must convert CIImage to a CGImage, then CGImage to an UIImage, and then UIImage to NSData.
static let context = CIContext(options:nil);
let tempImage:CGImageRef = context.createCGImage(ciImage, fromRect: ciImage.extent())
let image = UIImage(CGImage: tempImage);
let imageData: NSData? = UIImageJPEGRepresentation(image, 0.6);

Swift - saving and retrieving images from userDefaults

I'm trying to save images retrieved from Parse.com like this:
let userImageFile = object["Image"] as PFFile
userImageFile.getDataInBackgroundWithBlock {
(imageData: NSData!, error: NSError!) -> Void in
if error == nil {
image = UIImage(data:imageData)
let imageToSave:NSData = UIImagePNGRepresentation(image)
self.saveImage(intRandomNumb, retImage: imageToSave)
}
}
where the saveImage-function looks like this:
func saveImage(imagepath:Int, retImage:NSData){
println("image is being saved")
let defaults = NSUserDefaults.standardUserDefaults()
let imagePathName = "\(imagepath)"
defaults.setObject(retImage, forKey: imagePathName)
}
and later, I'm trying to display this image like this:
var point = gestureRecognizer.locationInView(self.tv)
if let indexPath = self.tv.indexPathForRowAtPoint(point)
{
let data = mainList[indexPath.row] as SecondModel
let fileRef = data.fileReference
let intFileRef = Int(fileRef)
println(intFileRef)
let defaults = NSUserDefaults.standardUserDefaults()
let usedKeyName = "\(intFileRef)"
if let photo = defaults.objectForKey(usedKeyName) as? UIImage {
println("Image created")
let photo = defaults.objectForKey(usedKeyName) as UIImage
var imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
imageView.image = photo
self.view.addSubview(imageView)
}
and the "Image created" never gets printed which means the retrieving somehow doesn't work.
I'm not quite sure if you're able to save images to the userdefaults like I've done here, but that was the best I could come up with, and I couldn't find any previous questions like this for Swift.
Any suggestions on how to proceed would be appreciated.
SOLUTION: The problem was that I tried to load the image directly as a UIImage. I also had to convert the NSData to a UIImage, this all happens in the last section of the code displayed above. Finally my code looks like this:
if let photo = defaults.objectForKey("\(intFileRef)") as? NSData {
println("Image created")
let photo = defaults.objectForKey("\(intFileRef)") as NSData
let imageToView:UIImage = UIImage(data: photo)
var imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
imageView.image = imageToView
self.view.addSubview(imageView)
}
I hope this can help others struggling with something similar to this.
Swift 3
Hey, try this beautiful code here:
Convert your UIImage to Data.
PNG:
yourDataImagePNG = UIImagePNGRepresentation(yourUIImageHere)
JPEG :
yourDataImageJPG = UIImage(data: yourUIImageHere,scale:1.0)
Save in UserDefaults.
UserDefaults().set(yourDataImagePNG, forKey: "image")
Recover from:
UserDefaults.standard.object(forKey: "image") as! Data
I hope to help!
It seems like you do not call defaults.synchronize() so it's not written to the defaults file.

Swift NSImage to CGImage

How can I convert a NSImage to CGImage in Swift? In Objective-C I did it like this:
- (CGImageRef)CGImage {
NSData *imageData = self.TIFFRepresentation;
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CGImageRef maskRef = CGImageSourceCreateImageAtIndex(source, 0, NULL);
return maskRef;
}
Now I tried with:
extension NSImage {
var CGImage: CGImageRef {
get {
let imageData = self.TIFFRepresentation
let source = CGImageSourceCreateWithData(imageData as CFDataRef, nil)
let maskRef = CGImageSourceCreateImageAtIndex(source, UInt(0), nil)
return maskRef;
}
}
}
I can't compile, I'm getting the error: Could not find an overload for 'init' that accepts the supplied arguments' at the line let maskRef ...
Here's what I'm using to convert NSImage to CGImage:
let image = NSImage(named:"image")
if let image = image {
var imageRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
let imageRef = image.cgImage(forProposedRect: &imageRect, context: nil, hints: nil)
}
Swift 5 code :-
if let image = NSImage(named: "Icon"){
let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil)
}
Ah, I found the solution. It's because in Swift you only the an unmanaged object (I just did not really understand, what this means). But this code now works:
extension NSImage {
var CGImage: CGImageRef {
get {
let imageData = self.TIFFRepresentation
let source = CGImageSourceCreateWithData(imageData as CFDataRef, nil).takeUnretainedValue()
let maskRef = CGImageSourceCreateImageAtIndex(source, UInt(0), nil)
return maskRef.takeUnretainedValue();
}
}
}
For Swift 4.0, XCode 9.2:
extension NSImage {
#objc var CGImage: CGImage? {
get {
guard let imageData = self.tiffRepresentation else { return nil }
guard let sourceData = CGImageSourceCreateWithData(imageData as CFData, nil) else { return nil }
return CGImageSourceCreateImageAtIndex(sourceData, 0, nil)
}
}
}
A Swift 5 implementation:
extension NSImage {
var CGImage: CGImage {
get {
let imageData = self.tiffRepresentation!
let source = CGImageSourceCreateWithData(imageData as CFData, nil).unsafelyUnwrapped
let maskRef = CGImageSourceCreateImageAtIndex(source, Int(0), nil)
return maskRef.unsafelyUnwrapped
}
}
}

Resources