AppleTv / TvOS - resizing TopShelf images in TVContentItems stored in ImageURL

I am using TopShelf on Apple tvOS. I uploaded the images and assigned imageURL from TVContentItems . The aspect ratio of the downloaded images does not fit the TopShelf images correctly. I tried resizing by adding width + height to the image link.

www.mydownloadedimages.com/{width} x {height}

But that did not work.

Is it possible to change the size on the client side in any other way. In the TVContentItem class, I only have an NSURL object. The UIImage object is missing.

Thank you very much.

Here are the Apple 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 acceptable for the Top Shelf style, the system reserves the right to scale the image in any way.

+5
source share
2 answers

You are right in saying that TVContentItem does not have a property of type UIImage . Since TVContentItem also accepts local file URLs in the imageURL property, a workaround could be:

  • capture UIImage from the Internet
  • creating a new image context with the image size of the top shelf
  • saving NSCacheDirectory
  • setting the local image URL as imageURL .

Here are the steps:

  • Create our TVContentItem object:

     let identifier = TVContentIdentifier(identifier: "myPicture", container: wrapperID)! let contentItem = TVContentItem(contentIdentifier: identifier )! 
  • Install contentItem imageShape :

     contentItem.imageShape = .HDTV 
  • Take an image from the Internet. In fact, I did this synchronously, you can also try using other async methods for this ( 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 a 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 have already set the topShelfStyle property, get the size of the top shelf image using the TVTopShelfImageSizeForShape method. This will be the context size of your image:

     let shapeSize : CGSize = TVTopShelfImageSizeForShape(contentItem.imageShape, self.topShelfStyle) 
  • Create your shapeSize image context and draw the loaded image into the rect context. Here you can make all changes to the image to adjust it to the desired size. In this example, I took a square image from Instagram, and I put the white stripes of the mailbox on the right and left.

     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 in your NSCacheDirectory and set the image path as the contentItem imageURL .

     UIImageJPEGRepresentation(newImage, 0.8)!.writeToFile(filepath, atomically: true) contentItem.imageURL = NSURL(fileURLWithPath: filepath) 
  • Fill your TVContentItem other information (for example, name, internal link, etc.), run the extension of the top shelf ... et voilà! tvOS Screenshot

+4
source

I would like to add the answer to Nicolau Giantcchi. The Top Shelf extension will work in the main thread, so using methods like UIImageJPEGRepresentation or UIImagePNGRepresentation sometimes stops the Top Shelf thread that prints this to the console:

Program terminated with exit code: 0

To fix this, you can wrap your code as follows:

 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 } } 
0
source

Source: https://habr.com/ru/post/1241896/


All Articles