UIImage init with scale in swift says "Extra Argument" Erroneously - ios

OK. This is whacky. I've checked the various answers above, and this is the only one that seems to really hit the mark.
However, there doesn't seem to be an answer.
I am using Swift to create a new UIImage, exactly like this (Objective-C version):
UIImage *myImage = [[UIImage alloc] initWithCGImage: aCGImageRefAllocatedPreviously scale:aCGFloatScaleCalculatedPreviously orientation:UIImageOrientationUp];
That works fine. However, when I try the same exact call in Swift:
let myImage = UIImage ( CGImage: aCGImageAllocatedPreviously, scale:aCGFloatScaleCalculatedPreviously, orientation:UIImageOrientation.Up )
I get a compiler error, telling me that "scale" is an extra parameter.
This is the kind of error that you get when the signature is wrong.
However, it isn't wrong (as far as I can tell).
What I am doing, is creating a tutorial by exactly replicating an Objective-C function in Swift (I know, I know, Swift is different, so I shouldn't exactly replicate, but, as Bill Murray would say, "Baby Steps").
I'm wondering how the heck I'm screwing up.
If I call it with just the image (no scale or orientation), it works fine, but I need that scale.

I tried this in the playground and was able to get this code to compile:
import UIKit
import AVFoundation
let myImage = UIImage(CGImage: nil,
scale:0,
orientation:UIImageOrientation.Up)
This syntax also works:
let newImage = UIImage.init(CGImage: nil,
scale:0,
orientation:UIImageOrientation.Up )

OK. I figgered it out. I was a knucklehead.
I need to use takeRetainedValue() on the CGImage, like so:
let myImage = UIImage ( CGImage: aCGImageAllocatedPreviously.takeRetainedValue(),scale:aCGFloatScaleCalculatedPreviously,orientation:UIImageOrientation.Up )
That satisfies the signature.

Related

How to take SnapShot of UIImageView And save it to the PhotoLibrary Swift

Hey I've looked at a lot of other question and tried to combine things to get the result but I have no luck.
Code:
UIGraphicsBeginImageContextWithOptions(self.ImageView.frame.size, false, UIScreen.main.scale)
// Draw view in that context
self.ImageView.drawHierarchy(in: self.ImageView.bounds, afterScreenUpdates: true)
// And finally, get image
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let imageRepresentation = UIImagePNGRepresentation(image)
let imageData = UIImage(data: imageRepresentation!)
UIImageWriteToSavedPhotosAlbum(imageData!, nil, nil, nil)
Sometimes I get this error and other times I don't. Is there a way to check to see if it would throw an error before? Also, I have never seen this error and really don't know what it is telling me
Error:
9: failed assertion `Fragment Function(ca_uber_fragment_lp0_cp1_fo0): The pixel format (MTLPixelFormatRGBA16Unorm) of the texture (name:) bound at index 0 is incompatible with the data type (MTLDataTypeHalf) of the texture parameter (img_tex_0A [[texture(0)]]). MTLPixelFormatRGBA16Unorm is compatible with the data type(s) (
The times that it doesn't crash with this error it works perfectly

Is HEIC/HEIF Supported By UIImage

I was under the impression that UIImage would support HEIC/HEIF files introduced in iOS 11. In my testing that does not appear to be the case though. If I do let image = UIImage(named: "test") which points to test.heic then image is nil. If I use an image literal then it crashes the app. Wondering if this is not implemented yet for now. Thanks.
While Zhao's answer works, it is fairly slow. The below is about 10-20 times faster. It still doesn't work in the simulator for some reason though so keep that in mind.
func convert(url: URL) -> UIImage? {
guard let source = CGImageSourceCreateWithURL(url as CFURL, nil) else { return nil }
guard let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil) else { return nil }
return UIImage(cgImage: cgImage)
}
This is kind of outlined on page 141 from the slides of a WWDC session but wasn't super clear to me before: https://devstreaming-cdn.apple.com/videos/wwdc/2017/511tj33587vdhds/511/511_working_with_heif_and_hevc.pdf
Unfortunately I still haven't been able to figure out a way to use images in the xcassets folder so you'll either have to include the files outside of assets or pull from on the web. If anyone knows a way around this please post.
In Xcode 10.1 (10B61), UIImage(named: "YourHeifImage") works just like other assets.
Interestingly though, when you want to try this out …and you AirDrop a HEIF pic from your (e.g. iPhone) Photos to your mac, it will get the extension .HEIC (all caps). When you then add that image to your Xcode xcassets, Xcode complains about an incorrect extension:
….xcassets: warning: Ambiguous Content: The image set "IMG_1791" references a file "IMG_1791.HEIC", but that file does not have a valid extension.
If you first change the extension to the lower-case .heic, and then add it to xcassets, all is well.
You can load HEIF via CIImage, then convert to UIImage
CIImage *ciImage = [CIImage imageWithContentsOfURL:url];
imageView.image = [UIImage imageWithCIImage:ciImage];

Swift - Create a GIF from Images and turn it into NSData

This might be an amateur question, but although I have searched Stack Overflow extensibly, I haven't been able to get an answer for my specific problem.
I was successful in creating a GIF file from an array of images by following a Github example:
func createGIF(with images: [NSImage], name: NSURL, loopCount: Int = 0, frameDelay: Double) {
let destinationURL = name
let destinationGIF = CGImageDestinationCreateWithURL(destinationURL, kUTTypeGIF, images.count, nil)!
// This dictionary controls the delay between frames
// If you don't specify this, CGImage will apply a default delay
let properties = [
(kCGImagePropertyGIFDictionary as String): [(kCGImagePropertyGIFDelayTime as String): frameDelay]
]
for img in images {
// Convert an NSImage to CGImage, fitting within the specified rect
let cgImage = img.CGImageForProposedRect(nil, context: nil, hints: nil)!
// Add the frame to the GIF image
CGImageDestinationAddImage(destinationGIF, cgImage, properties)
}
// Write the GIF file to disk
CGImageDestinationFinalize(destinationGIF)
}
Now, I would like to turn the actual GIF into NSData so I can upload it to Firebase, and be able to retrieve it on another device.
To achieve my goal, I have two options: Either to find how to use the code above to extract the GIF created (which seems to directly be created when creating the file), or to use the images on the function's parameters to create a new GIF but keep it on NSData format.
Does anybody have any ideas on how to do this?
Since nobody went ahead for over six months I will just put the answer from #Sachin Vas' comment here:
You can get the data using NSData(contentsOf: URL)

GPUImage Filter Returning nil

I've been trying to apply the GPUImageHoughTransformLineDetector to a UIImage in Swift but it's giving me nothing and for a couple of hours now i can't figure what i'm doing wrong.
Heres my code :
func lineDetection(image: UIImage)-> UIImage {
let stillImage = GPUImagePicture(image: image)
let filter = GPUImageHoughTransformLineDetector()
let lineGenerator = GPUImageLineGenerator()
lineGenerator.forceProcessingAtSize(image.size)
lineGenerator.setLineColorRed(1.0,green: 0.0, blue: 0.0)
filter.linesDetectedBlock = { (lineArray:UnsafeMutablePointer<GLfloat>, linesDetected:UInt, frameTime:CMTime) in
lineGenerator.renderLinesFromArray(lineArray, count:linesDetected, frameTime:frameTime)
}
stillImage.addTarget(filter)
let blendFilter = GPUImageAlphaBlendFilter()
blendFilter.forceProcessingAtSize(image.size)
let gammaFilter = GPUImageGammaFilter()
stillImage.addTarget(gammaFilter)
gammaFilter.addTarget(blendFilter)
lineGenerator.addTarget(blendFilter)
blendFilter.useNextFrameForImageCapture()
stillImage.processImage()
return filter.imageFromCurrentFramebuffer() // returns always nil <<
}
Must be something simple that i am missing but i simply am in "that rut" now. Thanks for understanding.
Update:
Sure enough it was simple, see my answer
Common sense not so common when you're following another guide.
I'll leave the question for it might help someone in the future with implementing the filter in Swift.
Changing:
filter.imageFromCurrentFramebuffer()
to:
blendFilter.imageFromCurrentFramebuffer()
Did it.

Save image with the correct orientation - Swift & Core Image

I'm using Core Image in Swift for editing photos and I have a problem when I save the photo. I'm not saving it with correct orientation.
When I get the picture from the Photo Library I'm saving the orientation in a variable as UIImageOrientation but I don't know how to set it back before saving the edited photo to the Photo Library. Any ideas how?
Saving the orientation:
var orientation: UIImageOrientation = .Up
orientation = gotImage.imageOrientation
Saving the edited photo to the Photo Library:
#IBAction func savePhoto(sender: UIBarButtonItem) {
let originalImageSize = CIImage(image:gotImage)
filter.setValue(originalImageSize, forKey: kCIInputImageKey)
// 1
let imageToSave = filter.outputImage
// 2
let softwareContext = CIContext(options:[kCIContextUseSoftwareRenderer: true])
// 3
let cgimg = softwareContext.createCGImage(imageToSave, fromRect:imageToSave.extent())
// 4
let library = ALAssetsLibrary()
library.writeImageToSavedPhotosAlbum(cgimg,
metadata:imageToSave.properties(),
completionBlock:nil)
}
Instead of using the metadata version of writeImageToSavedPhotosAlbum, you can use :
library.writeImageToSavedPhotosAlbum(
cgimg,
orientation: orientation,
completionBlock:nil)
then you can pass in the orientation directly.
To satisfy Swift, you may need to typecast it first:
var orientation : ALAssetOrientation = ALAssetOrientation(rawValue:
gotImage.imageOrientation.rawValue)!
As per my somewhat inconclusive answer here.
(As you have confirmed, this solution does indeed work in Swift - I derived it, untested, from working Objective-C code)
If you are interested in manipulating other information from image metadata, here are a few related answers I provided to other questions...
Updating UIImage orientation metaData?
Force UIImagePickerController to take photo in portrait orientation/dimensions iOS
How to get author of image in cocoa
Getting a URL from (to) a "picked" image, iOS
And a small test project on github that digs out image metadata from various sources (it's objective-C, but the principles are the same).
You are calling writeImageToSavedPhotosAlbum:metadata:completionBlock:... The docs on that method say:
You must specify the orientation key in the metadata dictionary to preserve the orientation of the image.

Resources