How to get Image Name used in an UIImage? - iphone

I am using an UIImage, in which I have an Image, and I want to know the name of image.

That functionality is not built-in to UIImage because images are not always loaded from files. However, you could create a custom UIImageView subclass to fit your needs.

It is not possible. UIImage instance contains the actual image data without any reference to the filename.

Images do not necessarily come from files or other named sources, so not all images even have a name. When you create an image from a file, you could store the name in a separate NSString*, and then refer to that stored name when necessary.

this code will help you out
NSString *imgName = [self.imgView1st image].accessibilityIdentifier;
NSLog(#"%#",imgName);
[self.imgView2nd setImage:[UIImage imageNamed:imgName]];

On later iOS versions it's possible to extract image name from the description. Aware, for the debug use only!
extension UIImage {
/// Extracts image name from a description.
/// * Example description: `<UIImage:0x60000278ce10 named(main: ic_timeline_milestone_bluedot) {16, 16}>`
/// * Example name: `ic_timeline_milestone_bluedot`
/// - warning: For the debug use only.
var name: String? {
let description = self.description
guard let regexp = try? NSRegularExpression(pattern: "\\(main: (.*)\\)", options: []) else { return nil }
guard let match = regexp.matches(in: description, options: [], range: description.fullRange).first else { return nil }
guard match.numberOfRanges > 0 else { return nil }
let idx1 = description.index(description.startIndex, offsetBy: range.lowerBound)
let idx2 = description.index(description.startIndex, offsetBy: range.upperBound)
return String(description[idx1..<idx2])
}
}

This answer (https://stackoverflow.com/a/72542728/897465) has (what I believe) the best answer:
let img = UIImage(named: "something")
img?.imageAsset?.value(forKey: "assetName")
Here's a handy extension for it:
extension UIImage {
var containingBundle: Bundle? {
imageAsset?.value(forKey: "containingBundle") as? Bundle
}
var assetName: String? {
imageAsset?.value(forKey: "assetName") as? String
}
}

Related

Need help about UIImage to change into a string

Need help...
private func classifyImage() {
let currentImageName = classifyimage
guard let image = UIImage(named: currentImageName?.convertToBuffer() as! String),
let resizedImage = image.resizeImageTo(size:CGSize(width: 224, height: 224)),
let buffer = resizedImage.convertToBuffer()
else {
return
}
let output = try? model.prediction(image: buffer)
}
Originally the codes should be produced as arrays but I'm trying to put image input without arrays and recognize the images. It keep saying it has to be a string and I have placed an unwrapped but still it doesn't work... Any idea what to do?

how to store [UIImage] into Core Data and retrieve to [UIImage] from binary date

my code is like these:
//save to core data
func addPaper(){
let paper = Paper(context: self.context)
paper.id = UUID()
paper.subject = self.subject
paper.score = Float(self.score) ?? 0
paper.title = self.title
let imgs = try? NSKeyedArchiver.archivedData(withRootObject: self.images, requiringSecureCoding: true)
paper.images = imgs
try? self.context.save()
}
//retrieve to [UIImage]
let imgs = NSKeyedUnarchiver.unarchivedObject(ofClass: [UIImage], from: paper.images!)
there is an error tip:Static method 'unarchivedObject(ofClass:from:)' requires that '[UIImage]' conform to 'NSCoding'
I don't know what to do next, can anyone give me some help?
You should not store image in CoreData. Maybe store in base64 format, and you can encode/decode whenever you want.
Base64 To image:
func base64ToImage(data: String) -> Data{
let encodedImageData = data
let imageData = Data(base64Encoded: encodedImageData)
return imageData!
}
imageView.image = UIImage(data: dataDecoded)
Image to base64
func imageToBase64(image: UIImage) -> String {
return image.pngData()!
.base64EncodedString()
}
maybe you need this, any object can be saved to core data.
:https://stackoverflow.com/questions/56453857/how-to-save-existing-objects-to-core-data
I copied the following steps from others, hope it helps
1.making your custom types (Exercise) subclass of NSObject
2.setting the attribute's type in the core data model to Transformable
3.setting the CustomClass to [Exercise]

Swift Image Name Compare

I am using the below code to work out if the image name in box1Image is equal to "sallywin.png".
Id doesnt seem to work.
How would I go about coding this?
Any help much appreciated
if (box1Image.image?.isEqual(UIImage(named: "smswin.png")))! {
self.box1Image.image = UIImage(named:"sallywin.png")
}
You cannot directly compare two images are same. You can get the images as NSDATA and then you can compare two NSDATA values are equal.
You can compare 2 images using NSData.
let imageName1 : UIImage = UIImage(named: "Selected_1.png")!
let imageName2 : UIImage = UIImage(named: "UnSelected.png")!
let imageView = UIImageView(image: imageName1)
if imageCompare(imageView.image!, isEqualTo: imageName2)
{
print("TRUE")
}
else
{
print("FALSE")
}
func imageCompare(image1: UIImage, isEqualTo image2: UIImage) -> Bool {
let data1: NSData = UIImagePNGRepresentation(image1)!
let data2: NSData = UIImagePNGRepresentation(image2)!
return data1.isEqual(data2)
}

Rewriting metadata into .jpg file by using Swift 2.2 OS X

I'm try rewrite metadata from JPG file. I want addition one keyword to metadata. Xcode don't give any errors, but file not changed.
Here is my code:
var pathToOpenFile:NSURL?
Next I write path from file to variable "pathToOpenFile".
If user pushed ENTER button into NSTextField, then work action:
#IBAction func endEditKeys(sender: AnyObject) {
if (pathToOpenFile != nil) {
let imageSource = CGImageSourceCreateWithURL(pathToOpenFile!, nil)
let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource!, 0, nil)! as NSDictionary;
let exifDict = imageProperties.valueForKey("{IPTC}") as! NSDictionary;
var Keywords:[String] = exifDict.valueForKey("Keywords") as! [String];
Keywords.append("ANY")
exifDict.setValue(Keywords, forKey: "Keywords")
let type = CGImageSourceGetType(imageSource!)
let count = CGImageSourceGetCount(imageSource!)
let mutableData = NSMutableData(contentsOfURL: pathToOpenFile!)
let destination = CGImageDestinationCreateWithData(mutableData!, type!, count, nil)
let removeExifProperties: CFDictionary = exifDict
for i in 0..<count {
CGImageDestinationAddImageFromSource(destination!, imageSource!, i, removeExifProperties)
}
CGImageDestinationFinalize(destination!)
}
}
Can you help me, why it isn't work (not change metadata)? Thank you!
Thanks all!
It is working, just need rewrite .JPG file in end.
if let _ = try? mutableData!.writeToURL(pathToOpenFile!, options: NSDataWritingOptions.AtomicWrite) {
// if you need, do anything. For example "print ("Savig file")"
}

CMFormatDescription to CMVideoFormatDescription

I'm trying to get the resolution of the camera of a device using swift.
I'm using CMVideoFormatDescriptionGetDimensions which requires a CMVideoFormatDescription, but AVCaptureDevice.formatDescription returns a CMFormatDescription. I've tried a multitude of ways to cast CMFormatDescription to CMVideoFormatDescription and can't seem to get it working.
Below is a sample of the code that I'm using:
for format in device.formats as [AVCaptureDeviceFormat] {
let videoDimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription)
}
This doesn't seem possible in Swift at the moment. One solution then would be to write a helper function in objective-c, such as:
CMVideoDimensions CMFormatDescriptionGetDimensions(CMFormatDescriptionRef formatDescription)
{
if (CMFormatDescriptionGetMediaType(formatDescription) == kCMMediaType_Video)
return CMVideoFormatDescriptionGetDimensions(formatDescription);
else
return (CMVideoDimensions) {
.width = 0,
.height = 0
};
}
Include the header with the function prototype in the Swift bridging header so that it will be accessible as a global function from your Swift code.
I was able to get the resolution using the swift method below:
let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) as AVCaptureDevice
let formatDesc = captureDevice.activeFormat.formatDescription
let dimensions = CMVideoFormatDescriptionGetDimensions(formatDesc)
Here's a solution in pure Swift, really only usable for logging purposes and such. Paste the following function in your class or somewhere else:
func widthAndHeightFromTrack(track: AVAssetTrack) -> CGSize {
let str = track.formatDescriptions.description
let regex = try! NSRegularExpression(pattern: "[0-9]{2,4} x [0-9]{2,4}", options: [])
if let result = regex.firstMatchInString(str, options: [], range: NSMakeRange(0, str.characters.count)) {
let dimensionString = (str as NSString).substringWithRange(result.range)
let dimensionArray = dimensionString.componentsSeparatedByString(" x ")
let width = Int(dimensionArray[0])
let height = Int(dimensionArray[1])
return CGSize(width: width!, height: height!)
}
return CGSizeZero
}
Example usage:
let allTracks: AVAsset = someAVAsset.tracksWithMediaType(AVMediaTypeVideo)
let videoTrack = allTracks[0]
let videoTrackDimensions = widthAndHeightFromTrack(videoTrack)
// You now have a CGSize, print it
print("Dimensions: \(videoTrackDimensions)")
Of course, the above solution will completely break whenever Apple changes something in the string representation of the CMFormatDescription. But it's useful for logging the dimensions.
Maybe, question is too old, but the Swift issue is still not fixed.
public extension AVURLAsset {
var audioFormatDescription: CMAudioFormatDescription? {
if let track = self.tracks(withMediaType: .audio).first,
let untypedDescription = track.formatDescriptions.first {
// hacks, warnings, disablings of swiftlint below are wrork-around of
// Swift bug: it fails converting 'Any as CMFormatDescription'
let forceTyped: CMFormatDescription?
//swiftlint:disable force_cast
= untypedDescription as! CMAudioFormatDescription
//swiftlint:enable force_cast
if let description = forceTyped {
return description
} else {
return nil
}
} else {
return nil
}
}
}