Swift - setup photo output for RAW camera app - ios

Kind of new to Swift in general, but I'm trying to make a simple RAW camera app for fun. Apple's documentation says that to configure a photo output, you do
let query = photoOutput.isAppleProRAWEnabled ?
{ AVCapturePhotoOutput.isAppleProRAWPixelFormat($0) } :
{ AVCapturePhotoOutput.isBayerRAWPixelFormat($0) }
// Retrieve the RAW format, favoring Apple ProRAW when enabled.
guard let rawFormat =
photoOutput.availableRawPhotoPixelFormatTypes.first(where: query) else {
fatalError("No RAW format found.")
}
but I've been getting an error with the first let statement which says "'isAppleProRAWEnabled' is only available in iOS 14.3 or newer." Is there any way to force it to check for ProRaw, even not on iOS 14.3? I'm not even interested in using ProRaw, but I can't figure out how to get rid of the check and just select the classic RAW format (which I think is the bayer format). If anyone knows a workaround, that would be great!

You can query for the Bayer RAW format as below:
let rawFormatQuery = {AVCapturePhotoOutput.isBayerRAWPixelFormat($0)}
guard let rawFormat = photoOutput.availableRawPhotoPixelFormatTypes.first(where: rawFormatQuery) else {
fatalError("No RAW format found.")
}
Then you set your photo settings using the raw format:
let photoSettings = AVCapturePhotoSettings(rawPixelFormatType: rawFormat,
processedFormat: processedFormat)
Finally, you call your capture delegate as described in the Apple documentation (which I think is where you got the code above).
https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/capturing_photos_in_raw_and_apple_proraw_formats

Related

Unable to detect QRCode from image using MLKit

I am using MLKIt for detect QRCode from image. for andrid it is working proper, for ios I am using below pods
pod 'GoogleMLKit/BarcodeScanning'
Here is sample code detect QRcode from image which picked from gallery. every time features array comes empty.
let format: BarcodeFormat = BarcodeFormat.all
let barcodeOptions = BarcodeScannerOptions(formats: format)
let visionImage = VisionImage(image: image)
visionImage.orientation = image.imageOrientation
let barcodeScanner = BarcodeScanner.barcodeScanner(options: barcodeOptions)
barcodeScanner.process(visionImage) { features, error in
guard error == nil, let features = features, !features.isEmpty else {
// Error handling
return
}
// Recognized barcodes
print("Data :: \(features.first?.rawValue ?? "")")
}
We noticed this may happen when there are no padding around the QR code, I also tried to add some padding to it: and it works after that. Could you confirm that it works?
On the other side, ML Kit is also working on a public document on this limitation. Thanks for reporting this.
Julie from ML Kit team

How to generate code128 barcode with special character '¿'?

I am developing application with ability to scan barcodes but i have problem with some characters which mess up everything for me. Same problem occured on android and i fixed it but i can't fix it on swift in same fashion.
I have tried multiple libraries and native ways to generate image of code128 barcode from provided String. It works on everything but special characters like '¿'. I tried everything i read after googling problem but i still could not fix it.
extension UIImage {
convenience init?(barcode: String) {
let data = barcode.data(using: .ascii)
guard let filter = CIFilter(name: "CICode128BarcodeGenerator") else {
return nil
}
filter.setValue(data, forKey: "inputMessage")
guard let ciImage = filter.outputImage else {
return nil
}
self.init(ciImage: ciImage)
}
}
let barcode = UIImage(barcode: "some text")
Everything works fine when scanning this exact barcode image from card and saving the value. It even says that ";038388¿" is type code128, but when I try to generate code128 barcode image out of it, somehow it has problem with "¿" character.
Code128 is defined as only capable of encoding ASCII, but ASCII does not have the "¿" character.
The conversion let data = barcode.data(using: .ascii) fails.
I would recommend catching this early using code like
guard let data = barcode.data(using: .ascii) else {
return nil
}

Integrate KML on offline Google Map iOS

I want to create a kml file programmatically in iOS Swift4. I surfed a lot regarding offline GoogleMaps & saving data in kml file, but I haven't found any relevant material regarding this. In short, I just want to store some POI in kml & display it in offline Googlemap!!
KML is an XML document scheme. You can write it in any way you see fit. Use a dedicated XML encoder or brute force using strings.
The full spec is documented at https://developers.google.com/kml/documentation/kmlreference
You may find examining existing KML files useful to show example structures.
Here is an example brute force encoder to encode a set of labeled placemarks…
Raw strings will need to be XML escaped before writing to file.
You may find Google Toolbox for Mac useful here.
class KMLWriter {
func createKMLFormat(_ logs:[DDBLogEntry])->String {
var kml = preamble()
for log in logs {
kml += placemarkForLog(log)
}
terminate(&kml)
return kml
}
func placemarkForLog(_ log:DDBLogEntry)->String {
let name = log.userContent ?? "empty"
let time = log.dateCreated ?? Date()
let timeStamp = Date.UTCDateFormatter.string(from: time)
return "<Placemark>\n<name>\(name)</name>\n<Point><coordinates>\(log.longitude ?? 0),\(log.latitude ?? 0),\(log.elevation ?? 0)</coordinates></Point>\n<TimeStamp><when>\(timeStamp)</when></TimeStamp>\n</Placemark>\n"
}
func preamble()->String {
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n<Document>\n"
}
func terminate(_ kml:inout String) {
kml += "</Document>\n</kml>\n"
}
}

Problems with structs in Swift and making a UIImage from url?

Alright, I am not familiar with structs or the ordeal I am dealing with in Swift, but what I need to do is create an iMessage in my iMessage app extension with a sticker in it, meaning the image part of the iMessage is set to the sticker.
I have pored over Apple's docs and https://www.captechconsulting.com/blogs/ios-10-imessages-sdk-creating-an-imessages-extension but I do not understand how to do this or really how structs work. I read up on structs but that has not helped me accomplishing what Apple does in their sample code (downloadable at Apple)
What Apple does is they first compose a message, which I understood, taking their struct as a property, but I take sticker instead
guard let conversation = activeConversation else { fatalError("Expected a conversation") }
//Create a new message with the same session as any currently selected message.
let message = composeMessage(with: MSSticker, caption: "sup", session: conversation.selectedMessage?.session)
// Add the message to the conversation.
conversation.insert(message) { error in
if let error = error {
print(error)
}
}
They then do this (this is directly from sample code) to compose the message:
fileprivate func composeMessage(with iceCream: IceCream, caption: String, session: MSSession? = nil) -> MSMessage {
var components = URLComponents()
components.queryItems = iceCream.queryItems
let layout = MSMessageTemplateLayout()
layout.image = iceCream.renderSticker(opaque: true)
layout.caption = caption
let message = MSMessage(session: session ?? MSSession())
message.url = components.url!
message.layout = layout
return message
}
}
Basically this line is what Im having the problem with as I need to set my sticker as the image:
layout.image = iceCream.renderSticker(opaque: true)
Apple does a whole complicated function thing that I don't understand in renderSticker to pull the image part out of their stickers, and I have tried their way but I think this is better:
let img = UIImage(contentsOfURL: square.imageFileURL)
layout.image = ing
layout.image needs a UIImage, and I can get the imageFileURL from the sticker, I just cant get this into a UIImage. I get an error it does not match available overloads.
What can I do here? How can I insert the image from my sticker into a message? How can I get an image from its imageFileURL?
I'm not sure what exactly the question is, but I'll try to address as much as I can --
As rmaddy mentioned, if you want to create an image given a file location, simply use the UIImage constructor he specified.
As far as sending just a sticker (which you asked about in the comments on rmaddy's answer), you can insert just a sticker into an iMessage conversation. This functionality is available as part of an MSConversation. Here is a link to the documentation:
https://developer.apple.com/reference/messages/msconversation/1648187-insert
The active conversation can be accessed from your MSMessagesAppViewController.
There is no init(contentsOfURL:) initializer for UIImage. The closest one is init(contentsOfFile:).
To use that one with your file URL you can do:
let img = UIImage(contentsOfFile: square.imageFileURL.path)

How to obtain video metadata from a video stored on Dropbox?

I don't know what I can do to obtain the duration of a video stored on Dropbox, thanks to the SwiftyDropbox API.
It sounds like these informations should be in an instance of Files.VideoMetadata class
I tried to use the getMetadata methods but the results doesn't contains the video duration, which is what I expect to get.
This is my current code :
Dropbox.authorizedClient!
.files
.getMetadata(path: file.pathLower!, includeMediaInfo: true)
.response({ (result, err) in
if let metadata = result as? Files.FileMetadata {
print(metadata.name)
if metadata.mediaInfo != nil {
switch metadata.mediaInfo! as Files.MediaInfo {
case .Pending:
print("Pending")
case .Metadata(let mediaMetadata):
print(mediaMetadata)
}
}
}
})
mediaMetadata contains {}, and I can't get the duration of the video, nor other properties.
It seems it's because my video uploaded on Dropbox is in the .mov format. Any solutions in this case ?
First, make sure you're calling getMetadata with includeMediaInfo set to true. (Also, this was only recently added, so make sure you're running the latest version of SwiftyDropbox.)
The resulting FileMetadata will hopefully have MediaInfo set to an instance of MediaMetadata. (It could also be Pending though, so be careful of that.)
Once you are looking at the MediaMetadata though, note that its fields are all set as optional, meaning it's unfortunately not guaranteed that they will be available.
This is because while Dropbox does make a best effort to extract this metadata, it can't always do so. This can vary from file to file.
You were actually very close, here is how you get the duration for videos:
if metadata.mediaInfo != nil {
switch metadata.mediaInfo! as Files.MediaInfo {
case .pending:
print("Pending")
case .metadata(let mediaMetadata):
switch mediaMetadata {
case let videoMetadata as Files.VideoMetadata:
print(videoMetadata)
print(videoMetadata.duration)
case let photoMetadata as Files.PhotoMetadata:
print(photoMetadata)
default: break
}
}
}
You can use this to determine weather a file is a video or photo as well

Resources