How to display local JPG image in a PFImageView - swift

I have several PFImageViews that are there to show images downloaded from Parse. However, there is one local image that I want to be able to load when I desire. For some reason, this code isn't working. Any help is greatly appreciated, thanks!
In cellForRowAtIndexPath:
let checkInImage = UIImage(named: "checkin.jpg")!
let checkInFile = UIImageJPEGRepresentation(checkInImage, 1.0)!
let imagePFFile = PFFile(data: checkInFile)!
tableViewCell.PFImageViewOne.file = imagePFFile
tableViewCell.PFImageViewOne.loadInBackground()

Since PFImageView is a subclass of UIImageView, you should be able to just set the image view's image property to your image like this:
tableViewCell.PFImageViewOne.image = checkInImage

Related

Converting UIImage to Data throws unsupported file format

I'm using the image picker to select a photo from photo library or to take a camera and in my imagePickerController function, I get the UIImage and try to convert it to an Image Data like this
let uiImage = info.[UIImagePickerController.Infokey.originalImage] as! UIImage
let imageData = uiImage.jpegData(compressionQuality: 1)! // this line throws error
And I keep getting this error
findWriterForTypeAndAlternateType:119: unsupported file format 'public.heic'
And also when I try to update my imageview like this Image(uiImage) the view gets updated but I don't know why I'm getting that error.
Can someone tell me what I'm doing wrong?
Okay... I've got it working. I don't know for what reason, but I changed myimageData to this:
let imageData = Data((uiImage.pngData())!)

Image loading taking more time in swift

I am working on an application, where I am loading some images from the server and showing it on table view using Alamofire. But the problem is it is taking so much time to load the image. I want to show the image, like a blurry image until the time image is not loading. Please, someone, help me.
cell.profileImageView?.pin_setImage(from: URL(string: modelArray[indexPath.row]))
This one is the solution using Kingfisher pod. You can set an activity Indicator while image is loaded.
let imageUrl = modelArray[indexPath.row]
//set activity indicator until image is loaded
cell.profileImageView?.kf.indicatorType = .activity
if let url = URL(string: imageUrl) {
let resource = ImageResource(downloadURL: url)
cell.profileImageView?.kf.setImage(with: resource)
}

NSView to PDF and PNG: Why is the outcome so different?

I am trying to safe an NSView to an PNG.
I start with the NSView and then call dataWithPDF or cacheDisplay for PNG. The code to do both looks like this.
guard view.lockFocusIfCanDraw() else {
assert (false)
return
}
let pdfData = view.dataWithPDF(inside: rect)
guard let imgData = view.bitmapImageRepForCachingDisplay(in: rect) else {
assert(false)
}
view.cacheDisplay(in: rect, to: imgData)
view.unlockFocus()
try pdfData.write(to: pdfName, options: .atomic)
let pngData = imgData.representation(using: .png, properties: [:])
try pngData!.write(to: pngName, options: .atomic)
So far, so good. However, this is the different outcome.
PDF (correct!)
And this is the PNG output. As one can see, the subviews aren't included. The arrows are drawn as part of view
Why is the outcome so different?
Many thanks in advance!
Ok, I found the answer. Thanks to "View Debugging" did I see that the subviews use a layer (self.wantsLayer = true). And layers are not finding their way into the PNG, but into the PDF. Not sure whether this is a bug or a feature. However, now I can fix the PNG output.
Why is the outcome so different?
Trying your code using a different (I obviously don't have your view) view with subviews works as expected and the PNG is fine. So it has to be something to do with your views, but I can make no suggestion as to what. However...
As you've got valid PDF data you can generate your PNG from that using something like:
let captured = NSImage(data:pdfData)
let rep = NSBitmapImageRep(data:(captured?.tiffRepresentation)!)
let pngData = rep?.representation(using: NSPNGFileType, properties:[:])
(that is Swift 3, hence NSPNGFileType rather than .png)
This of course doesn't solve whatever problem you have, it avoids it :-) You should really figure out why your views are failing and treat this as a temporary band aid (assuming it works for you...).
HTH

NSView dataWithPDF inside rect but with background view

I wan´t to take a screenshot of a NSView but when I do this, I get an image without the background. All the subviews are show, but not the background. I use this code:
if let image = NSImage(data: background.dataWithPDF(inside: background.bounds)) {
let imageView = NSImageView(image: image)
imageView.imageScaling = .scaleProportionallyUpOrDown
return NSImageView(image: image)
}
I thought, ok when I get only the subviews, then I will make a screenshot of the superview and I thried the following:
if let superview = background.superview, let image = NSImage(data: superview.dataWithPDF(inside: background.frame)) {
let imageView = NSImageView(image: image)
imageView.imageScaling = .scaleProportionallyUpOrDown
return NSImageView(image: image)
}
But I get the same result. Even if I set the background color of my background view I don´t get an image without transparent background.
How can I resolve this?
thank you
Artur
I got an Answer:
background.lockFocus()
if let rep = NSBitmapImageRep(focusedViewRect: background.bounds){
let img = NSImage(size: background.bounds.size)
img.addRepresentation(rep)
return NSImageView(image: img)
}
background.unlockFocus()
You could have converted the views backing layer.backgroundColor to an image. Then assign the image to a backing image view that sits in the 0th index of your views heirarchy and use the method dataWithPDF -> that will successfully capture a background.

AppleTv / TvOS - Resize TopShelf Images in TVContentItems Saved to ImageURL

I am implementing TopShelf in Apple tvOS. I have downloaded images and assigned to imageURL of TVContentItems. The downloaded images aspect ratio does not fit into the TopShelf Images properly. I have tried to change the size by appending width + height to the image link.
www.mydownloadedimages.com/{width}x{height}
But it didn't work.
Can I do resizing at client end in any other way. In the TVContentItem class I have only have NSURL object. There is no UIImage Object.
Thanks a lot.
Here is Apple's documentation on Image Sizes and shapes
// ~ 2 : 3
// ~ 1 : 1
// ~ 4 : 3
// ~ 16 : 9
// ~ 8 : 3
// ~ 87 : 28
//#property imageShape
//#abstract A TVContentItemImageShape value describing the intended aspect ratio or shape of the image.
//#discussion For Top Shelf purposes: the subset of values which are //valid in this property, for TVContentItems in the topShelfItems property //of the TVTopShelfProvider, depends on the value of the topShelfStyle //property of the TVTopShelfProvider:
TVTopShelfContentStyleInset:
valid: TVContentItemImageShapeExtraWide
TVTopShelfContentStyleSectioned:
valid: TVContentItemImageShapePoster
valid: TVContentItemImageShapeSquare
valid: TVContentItemImageShapeHDTV
When the value of this property is not valid for the Top Shelf style, the system reserves the right to scale the image in any way.
You're right saying that the TVContentItem has no UIImage type property. Since TVContentItem also accepts local file URLs in the imageURL property, a workaround can be:
grabbing the UIImage from internet
creating a new image context with the size of the top shelf image
saving it into the NSCacheDirectory
setting the local image URL as imageURL.
Here are the steps:
Let's create our TVContentItem object:
let identifier = TVContentIdentifier(identifier: "myPicture", container: wrapperID)!
let contentItem = TVContentItem(contentIdentifier: identifier )!
Set the contentItem's imageShape:
contentItem.imageShape = .HDTV
Grab the image from Internet. Actually I did this synchronously, you can also try to use other async methods to get that (NSURLConnection, AFNetworking, etc...):
let data : NSData = NSData(contentsOfURL: NSURL(string: "https://s3-ak.buzzfed.com/static/2014-07/16/9/enhanced/webdr08/edit-14118-1405517808-7.jpg")!)!
Prepare the path where your image will be saved and get your UIImage from the data object:
let filename = "picture-test.jpg"
let paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)
let filepath = paths.first! + "/" + filename
let img : UIImage = UIImage(data: data)!
Assuming you've already set the topShelfStyle property, get the size of the top shelf image with the method TVTopShelfImageSizeForShape. This will be the size of your image context:
let shapeSize : CGSize = TVTopShelfImageSizeForShape(contentItem.imageShape, self.topShelfStyle)
Create your image context of shapeSize size and draw the downloaded image into the context rect. Here you can do all your modifications to the image to adjust it into the desired size. In this example I took a square image from Instagram and I put white letterbox bands on the right and left sides.
UIGraphicsBeginImageContext(shapeSize)
let imageShapeInRect : CGRect = CGRectMake((shapeSize.width-shapeSize.height)/2,0,shapeSize.height,shapeSize.height)
img.drawInRect(imageShapeInRect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
In the end, save this image into your NSCacheDirectory and set the image path as contentItem's imageURL.
UIImageJPEGRepresentation(newImage, 0.8)!.writeToFile(filepath, atomically: true)
contentItem.imageURL = NSURL(fileURLWithPath: filepath)
Complete your TVContentItem with other details (like title, internal link, etc...), run the top shelf extension... et voilà!
I would like to add to Nicola Giancecchi's answer. The Top Shelf extension will run on a non main thread so using methods like UIImageJPEGRepresentation or UIImagePNGRepresentation will sometimes stop the Top Shelf thread printing this in the console:
Program ended with exit code: 0
To fix this you can wrap your code like this:
DispatchQueue.main.sync {
UIImageJPEGRepresentation(newImage, 0.8)!.writeToFile(filepath, atomically: true)
let imageURL = NSURL(fileURLWithPath: filepath)
if #available(tvOSApplicationExtension 11.0, *) {
contentItem.setImageURL(imageURL, forTraits: .userInterfaceStyleLight)
contentItem.setImageURL(imageURL, forTraits: .userInterfaceStyleDark)
} else {
contentItem.imageURL = imageURL
}
}