Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Live PhotoをアニメーションGIFに書き出す
Search
Kei Ito
March 30, 2016
Technology
1.4k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Live PhotoをアニメーションGIFに書き出す
関西モバイルアプリ研究会 #12 の資料です
http://kanmoba.connpass.com/event/28411/
Kei Ito
March 30, 2016
More Decks by Kei Ito
See All by Kei Ito
20211015 Mac CatalystでmacOS用アプリを作る
itok
2
4.5k
20210219 Flutterに入門してみた
itok
1
4.1k
20201009 iOS 14 ウィジェットをつくってみた
itok
1
2.5k
20191206 Property Wrappers 入門
itok
0
1.7k
20190920 iOS 13 対応ではまった話
itok
1
2.5k
20190726 Background App Refresh Taskがやってきた
itok
0
2.3k
20190722 Firebase Remote Configでアドネットワークを管理する
itok
0
1.7k
20190419 iOSアプリで証明書の情報を参照する
itok
0
1.6k
20190412 Android TV向けアプリを作ってみる
itok
0
1.1k
Other Decks in Technology
See All in Technology
アクセスキーが漏れた日にやるべきこと- 無効化の先にある本当の対応
kazzpapa3
0
310
AI画像認識を活用したゲーム内決済処理検証の自動化
gree_tech
PRO
0
450
AI時代のアウトプット――変わったこと、変わらないこと / Devsumi 2026 Kansai #devsumi
jnchito
0
560
MIXIで活躍できるエンジニアを 若手社員目線で考えてみる
mixi_engineers
PRO
0
150
What's new in Go 1.27?
ciarana
0
430
Claude Teamプランの コスト最適化を考える
rfdnxbro
0
480
Introduction to Sansan, inc / Sansan Global Development Center, Inc.
sansan33
PRO
0
3.2k
コミュニティから始まった農業IoTとの7年間 ——人との関わりが教えてくれたこと
peacemaker07
0
110
内製AIチャットボット開発で学んだ Datadog Agent Observability活用術
mkdev10
0
130
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.2k
トークンマネジメントでAIにとって働きやすい環境を実現する
hikaruegashira
0
160
巨大気象データと戦う ― サロゲートモデル学習を高速化する圧縮技術
gpuunite_official
0
270
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
500
The Cult of Friendly URLs
andyhume
79
7k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
Raft: Consensus for Rubyists
vanstee
141
7.6k
Discover your Explorer Soul
emna__ayadi
2
1.3k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
560
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.5k
Transcript
-JWF1IPUPΛ Ξχϝʔγϣϯ(*'ʹ ॻ͖ग़͢ ؔϞόΠϧΞϓϦݚڀձ !JUPL@UXJU
!JUPL@UXJU w ͍ͱ͏͚͍ʢJUPLʣ w ɹɹɹɹɹɹͷதͷਓ w ެࢲڞʹϓϩάϥϚJ04.BDʢͨ·ʹ"OESPJE8JOEPXTʣ w IUUQJUPLKQ IUUQTPSBLB[FDPKQ
ॴ USZTXJGU։࠵த
-JWF1IPUP͔ͬͯͭͬͯ·͢ʙʁ ڞ༗͢Δͷ͕େมͳΜͰ͢ΑͶʙ Ξχϝʔγϣϯ(*'ʹ͢ΔΞϓϦ ͋ΔΈ͍ͨͳΜͰ͚͢ͲͶ͑ʙ
͋ɺͦΕɺͰ͖·͢Α "7'PVOEBUJPOͱ͔*NBHF*0͑
ͬͯΈͨ
ΰʔϧ
ඞཁͳͷ w J04Ҏ্ w 1IPUPT w "7'PVOEBUJPO w *NBHF*0 w
J1IPOFTT1MVT4&J1BE1SPJODI
-JWF1IPUPΛ୳͢ // get all images let result = PHAsset.fetchAssetsWithMediaType(.Image, options:
nil) var photoAsset: PHAsset? result.enumerateObjectsUsingBlock { (obj, idx, stop) -> Void in let asset = obj as! PHAsset if asset.mediaSubtypes.contains(.PhotoLive) { photoAsset = asset stop.memory = true } })
-JWF1IPUPΛ୳͢ let mgr = PHImageManager.defaultManager() mgr.requestLivePhotoForAsset(photoAsset, targetSize: CGSizeZero, contentMode: .Default,
options: nil) { (livePhoto, info) -> Void in if let livePhoto = livePhoto { self.livePhotoView.livePhoto = livePhoto } }
ಈըΛऔΓग़͢ // search movie in live photo let resources =
PHAssetResource.assetResourcesForLivePhoto(photo) for resource in resources { if resource.type == .PairedVideo { self.getMovieData(resource) break } }
ಈըΛऔΓग़͢ // load movie data let mgr = PHAssetResourceManager.defaultManager() mgr.requestDataForAssetResource(resource,
options: nil, dataReceivedHandler: { (data) -> Void in movieData.appendData(data) }) { (err) -> Void in do { try movieData.writeToURL(movieURL, options:.AtomicWrite) let movieAsset = AVAsset(URL: movieURL) self.convertToGif(movieAsset, resource: resource) } catch { } }
ը૾ΛऔΓग़͢ // generate thumbnails and write to gif let generator
= AVAssetImageGenerator(asset: movieAsset) // generate in any timelines generator.requestedTimeToleranceBefore = kCMTimeZero generator.requestedTimeToleranceAfter = kCMTimeZero // apply video transform generator.appliesPreferredTrackTransform = true generator.maximumSize = CGSizeMake(640, 640) generator.generateCGImagesAsynchronouslyForTimes(times) { (requested, image, actual, result, err) -> Void in // }
"OJNBUJPO(*'ʹॻ͖ग़͢ let gif = CGImageDestinationCreateWithURL (gifURL, kUTTypeGIF, numFrame, nil) let
frameProperty = .. // AVAssetImageGenerator’s loop { CGImageDestinationAddImage(gif, image, frameProperty) } let gifProperty = .. CGImageDestinationSetProperties(gif, gifProperty) CGImageDestinationFinalize(gif) self.webView.loadRequest(NSURLRequest(URL: gifURL))
ίʔυͪ͜Βʹ HJUIVCDPNJUPL-JWF1IPUP5P"OJNBUFE(JG