UICollectionView
で多くの画像と動画をユーザに表示するiOSアプリケーションを設計しています。私は、ビデオのサムネイルを生成し、それを表示することによってビデオを処理し、ビデオはユーザがサムネイルをクリックしたときにのみロードされます。今度は、base64
がblobs
とコード化された画像と動画をリモートの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エンコーディングを使うべきですか?リクエストが完了するまで
私は自分のデータベースにファイルのURLを格納し、それを私のjsonレスポンスに渡して、単にそのURLからダウンロードする機能を持たせるのが好きです。私は現在、これを私のアプリの別のセクションで使用しています。ここで私はプロフィール画像にURLを保存し、このようにダウンロードします。問題は、これらの画像は、FacebookやFacebookのような場所からではなく、ユーザーが作成したコンテンツであり、画像と動画をアップロードして私にできるURLを与えることができる有効なサービスが見つからないようです画像/ビデオにアクセスするために使用します。 – Alk
@mankee人気のあるものはAWS S3です。 – Code
SQLデータベースと同じサーバーにファイルを保存するためのput要求を使用しますか?または、これはアプリケーションからアクセス可能なURLを生成しません – Alk