2016-06-12 13 views
0

UICollectionViewで多くの画像と動画をユーザに表示するiOSアプリケーションを設計しています。私は、ビデオのサムネイルを生成し、それを表示することによってビデオを処理し、ビデオはユーザがサムネイルをクリックしたときにのみロードされます。今度は、base64blobsとコード化された画像と動画をリモートのmysqliデータベースに保存します。私の質問は、これらの画像や動画をアプリケーションに戻す最も効率的な方法です。現在、私は画像のサムネイルだけでなく、ビデオスナップショットを生成するには、次の機能を使用します。オンラインmysqlデータベースからUICollectionView Swiftに画像を読み込む

func RBSquareImageTo(image: UIImage, size: CGSize) -> UIImage? { 
    return RBResizeImage(RBSquareImage(image), targetSize: size) 
} 

func RBSquareImage(image: UIImage) -> UIImage? { 
    let originalWidth = image.size.width 
    let originalHeight = image.size.height 

    var edge: CGFloat 
    if originalWidth > originalHeight { 
     edge = originalHeight 
    } else { 
     edge = originalWidth 
    } 

    let posX = (originalWidth - edge)/2.0 
    let posY = (originalHeight - edge)/2.0 

    let cropSquare = CGRectMake(posX, posY, edge, edge) 

    let imageRef = CGImageCreateWithImageInRect(image.CGImage, cropSquare); 
    return UIImage(CGImage: imageRef!, scale: UIScreen.mainScreen().scale, orientation: image.imageOrientation) 
} 

func RBResizeImage(image: UIImage?, targetSize: CGSize) -> UIImage? { 
    if let image = image { 
     let size = image.size 

     let widthRatio = targetSize.width/image.size.width 
     let heightRatio = targetSize.height/image.size.height 

     // Figure out what our orientation is, and use that to form the rectangle 
     var newSize: CGSize 
     if(widthRatio > heightRatio) { 
      newSize = CGSizeMake(size.width * heightRatio, size.height * heightRatio) 
     } else { 
      newSize = CGSizeMake(size.width * widthRatio, size.height * widthRatio) 
     } 

     // This is the rect that we've calculated out and this is what is actually used below 
     let rect = CGRectMake(0, 0, newSize.width, newSize.height) 

     // Actually do the resizing to the rect using the ImageContext stuff 
     UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) 
     image.drawInRect(rect) 
     let newImage = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     return newImage 
    } else { 
     return nil 
    } 
} 
func videoSnapshot(vidURL: NSURL) -> UIImage? { 

    let asset = AVURLAsset(URL: vidURL) 
    let generator = AVAssetImageGenerator(asset: asset) 
    generator.appliesPreferredTrackTransform = true 

    let timestamp = CMTime(seconds: 1, preferredTimescale: 60) 

    do { 
     let imageRef = try generator.copyCGImageAtTime(timestamp, actualTime: nil) 
     return UIImage(CGImage: imageRef) 
    } 
    catch let error as NSError 
    { 
     print("Image generation failed with error \(error)") 
     return nil 
    } 
} 

私は、サムネイルとしてだけでなく、コンテンツを圧縮するために以下の機能を使用しての私のデータベースに送信しますPOSTリクエスト: - 1.5メガバイトと4〜6キロバイト程度サムネイル

func compressVideo(inputURL: NSURL, outputURL: NSURL, handler:(session: AVAssetExportSession)-> Void) 
{ 
    let urlAsset = AVURLAsset(URL: inputURL, options: nil) 

    let exportSession = AVAssetExportSession(asset: urlAsset, presetName: AVAssetExportPresetMediumQuality) 

    exportSession!.outputURL = outputURL 

    exportSession!.outputFileType = AVFileTypeQuickTimeMovie 

    exportSession!.shouldOptimizeForNetworkUse = true 

    exportSession!.exportAsynchronouslyWithCompletionHandler {() -> Void in 

     handler(session: exportSession!) 
    } 

} 

func compressImage(image:UIImage) -> NSData { 
    // Reducing file size to a 10th 

    var actualHeight : CGFloat = image.size.height 
    var actualWidth : CGFloat = image.size.width 
    let maxHeight : CGFloat = 1136.0 
    let maxWidth : CGFloat = 640.0 
    var imgRatio : CGFloat = actualWidth/actualHeight 
    let maxRatio : CGFloat = maxWidth/maxHeight 
    var compressionQuality : CGFloat = 0.5 

    if (actualHeight > maxHeight || actualWidth > maxWidth){ 
     if(imgRatio < maxRatio){ 
      //adjust width according to maxHeight 
      imgRatio = maxHeight/actualHeight; 
      actualWidth = imgRatio * actualWidth; 
      actualHeight = maxHeight; 
     } 
     else if(imgRatio > maxRatio){ 
      //adjust height according to maxWidth 
      imgRatio = maxWidth/actualWidth; 
      actualHeight = imgRatio * actualHeight; 
      actualWidth = maxWidth; 
     } 
     else{ 
      actualHeight = maxHeight; 
      actualWidth = maxWidth; 
      compressionQuality = 1; 
     } 
    } 

    let rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight); 
    UIGraphicsBeginImageContext(rect.size); 
    image.drawInRect(rect) 
    let img = UIGraphicsGetImageFromCurrentImageContext(); 
    let imageData = UIImageJPEGRepresentation(img, compressionQuality); 
    UIGraphicsEndImageContext(); 

    return imageData!; 
} 

これは500キロバイトの間で画像や動画になります。私はipad2でのみこれをテストしたので、新しいiPhoneを写真やビデオの撮影に使用すると、これらのサイズが大幅に増加すると思われます。現在私がやっていることはサーバーに1つのリクエストを送信することです。これはデータベース内のすべてのイメージとビデオのサムネイルを返しますが、サムネイルは一般的に低品質です。私はこの特定の状況で完全な画像と動画を読み込むより効率的な方法があるのだろうかと思います。私は、約10枚の画像(画面に表示されるもの)だけをロードする要求を送信するようなことを考えていました。ユーザーがスクロールすると、次の10枚の画像に対して別の要求が送信されます。ユーザーが十分に速くスクロールした場合、要求が完了するまで空白にします。あなたがこれを推薦する図書館はありますか、あるいはもっと効率的だと言う別のアプローチがありますか?この場合、私はbase64エンコーディングを使うべきですか?リクエストが完了するまで

答えて

0

セルは空白になりますかのように、長いサムネイルと1対空白のセルからのスムーズな移行があるとして、大丈夫ですダウン十分に速く

ユーザーがスクロールします。 FacebookやInstagramなどの人気アプリでも発生します。

この場合、base64エンコーディングを使用する必要がありますか?

効率性が懸念される場合は、おそらくそうではありません。一般に、次のようになります。

  • ファイル(サムネイル/ビデオ)に識別子を割り当てます。
  • 識別子をデータベースとクラウドの外部に、好ましくはCDNでファイルに格納します。
  • クライアントは、一度に複数の識別子をサーバから取得します。
  • クライアントは外部ロケーションからファイルをダウンロードし、キャッシュします。
+0

私は自分のデータベースにファイルのURLを格納し、それを私のjsonレスポンスに渡して、単にそのURLからダウンロードする機能を持たせるのが好きです。私は現在、これを私のアプリの別のセクションで使用しています。ここで私はプロフィール画像にURLを保存し、このようにダウンロードします。問題は、これらの画像は、FacebookやFacebookのような場所からではなく、ユーザーが作成したコンテンツであり、画像と動画をアップロードして私にできるURLを与えることができる有効なサービスが見つからないようです画像/ビデオにアクセスするために使用します。 – Alk

+0

@mankee人気のあるものはAWS S3です。 – Code

+0

SQLデータベースと同じサーバーにファイルを保存するためのput要求を使用しますか?または、これはアプリケーションからアクセス可能なURLを生成しません – Alk

関連する問題