Commit deb99315 authored by Quentin Muret's avatar Quentin Muret

gif: The app now reads gif pictures

Change-Id: Ifb6530095fb8175562762dee064e1b050038cd7f
Reviewed-by: Andreas Traczyk's avatarAndreas Traczyk <andreas.traczyk@savoirfairelinux.com>
parent c653c3fa
......@@ -283,6 +283,7 @@
6613A612214AFF4700B497D1 /* ScanViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6613A611214AFF4700B497D1 /* ScanViewController.storyboard */; };
66266FC021557D2F002757A6 /* ScanViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66266FBF21557D2F002757A6 /* ScanViewModel.swift */; };
66266FC4215C18F8002757A6 /* Emoji+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66266FC3215C18F8002757A6 /* Emoji+Helpers.swift */; };
6661C73A216D2EA300E48D94 /* Gif+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6661C739216D2EA300E48D94 /* Gif+Helpers.swift */; };
66ACB430214AE28C00A94162 /* ScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66ACB42F214AE28C00A94162 /* ScanViewController.swift */; };
66E6381221764C2C005EA2B0 /* GrowingTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66E6381121764C2C005EA2B0 /* GrowingTextView.swift */; };
66F295DE2166A5930044ED6F /* Devices+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F295DD2166A5930044ED6F /* Devices+Helpers.swift */; };
......@@ -654,6 +655,7 @@
6613A611214AFF4700B497D1 /* ScanViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ScanViewController.storyboard; sourceTree = "<group>"; };
66266FBF21557D2F002757A6 /* ScanViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanViewModel.swift; sourceTree = "<group>"; };
66266FC3215C18F8002757A6 /* Emoji+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Emoji+Helpers.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
6661C739216D2EA300E48D94 /* Gif+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Gif+Helpers.swift"; sourceTree = "<group>"; };
66ACB42F214AE28C00A94162 /* ScanViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanViewController.swift; sourceTree = "<group>"; };
66E6381121764C2C005EA2B0 /* GrowingTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GrowingTextView.swift; sourceTree = "<group>"; };
66F295DD2166A5930044ED6F /* Devices+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Devices+Helpers.swift"; sourceTree = "<group>"; };
......@@ -891,6 +893,7 @@
62E55B6C1F758E6F00D3FEF4 /* String+Helpers.swift */,
66F295DD2166A5930044ED6F /* Devices+Helpers.swift */,
66266FC3215C18F8002757A6 /* Emoji+Helpers.swift */,
6661C739216D2EA300E48D94 /* Gif+Helpers.swift */,
1A3D28A61F0EB9DB00B524EE /* Bool+String.swift */,
1A3D28A81F0EBF0200B524EE /* UIView+Ring.swift */,
1AABA7451F0FE9C000739605 /* UIColor+Ring.swift */,
......@@ -1859,6 +1862,7 @@
1A2D18C71F29180700B2C785 /* DeviceModel.swift in Sources */,
1A20418F1F1EAC0E00C08435 /* Coordinator.swift in Sources */,
0E49097C1FEACA4B005CAA50 /* CallViewModel.swift in Sources */,
6661C73A216D2EA300E48D94 /* Gif+Helpers.swift in Sources */,
1A2D18A11F27A6D600B2C785 /* LinkDeviceViewController.swift in Sources */,
1A0C4EDC1F1D4B7E00550433 /* WelcomeViewController.swift in Sources */,
1A2D18D81F2918EE00B2C785 /* MeDetailViewController.swift in Sources */,
......
//
// iOSDevCenters+GIF.swift
// GIF-Swift
//
// Created by iOSDevCenters on 11/12/15.
// Copyright © 2016 iOSDevCenters. All rights reserved.
//
import UIKit
import ImageIO
// FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
// Consider refactoring the code to use the non-optional operators.
fileprivate func < <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
switch (lhs, rhs) {
case let (varL?, varR?):
return varL < varR
case (nil, _?):
return true
default:
return false
}
}
extension UIImage {
public class func gifImageWithData(_ data: Data) -> UIImage? {
guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {
print("image doesn't exist")
return nil
}
return UIImage.animatedImageWithSource(source)
}
public class func gifImageWithUrl(_ url: URL) -> UIImage? {
guard let imageData = try? Data(contentsOf: url) else {
print("SwiftGif: Cannot turn image named \"\(url.path)\" into NSData")
return nil
}
return gifImageWithData(imageData)
}
class func delayForImageAtIndex(_ index: Int, source: CGImageSource!) -> Double {
var delay = 0.1
let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
let gifProperties: CFDictionary = unsafeBitCast(
CFDictionaryGetValue(cfProperties,
Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque()),
to: CFDictionary.self)
var delayObject: AnyObject = unsafeBitCast(
CFDictionaryGetValue(gifProperties,
Unmanaged.passUnretained(kCGImagePropertyGIFUnclampedDelayTime).toOpaque()),
to: AnyObject.self)
if delayObject.doubleValue == 0 {
delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,
Unmanaged.passUnretained(kCGImagePropertyGIFDelayTime).toOpaque()), to: AnyObject.self)
}
delay = delayObject as! Double
if delay < 0.1 {
delay = 0.1
}
return delay
}
class func gcdForPair(_ varA: Int?, _ varB: Int?) -> Int {
var varA = varA
var varB = varB
if varB == nil || varA == nil {
if varB != nil {
return varB!
} else if varA != nil {
return varA!
} else {
return 0
}
}
if varA < varB {
let varC = varA
varA = varB
varB = varC
}
var rest: Int
while true {
rest = varA! % varB!
if rest == 0 {
return varB!
} else {
varA = varB
varB = rest
}
}
}
class func gcdForArray(_ array: Array<Int>) -> Int {
if array.isEmpty {
return 1
}
var gcd = array[0]
for val in array {
gcd = UIImage.gcdForPair(val, gcd)
}
return gcd
}
class func animatedImageWithSource(_ source: CGImageSource) -> UIImage? {
let count = CGImageSourceGetCount(source)
var images = [CGImage]()
var delays = [Int]()
for rang in 0..<count {
if let image = CGImageSourceCreateImageAtIndex(source, rang, nil) {
images.append(image)
}
let delaySeconds = UIImage.delayForImageAtIndex(Int(rang),
source: source)
delays.append(Int(delaySeconds * 1000.0)) // Seconds to ms
}
let duration: Int = {
var sum = 0
for val: Int in delays {
sum += val
}
return sum
}()
let gcd = gcdForArray(delays)
var frames = [UIImage]()
var frame: UIImage
var frameCount: Int
for rang in 0..<count {
frame = UIImage(cgImage: images[Int(rang)])
frameCount = Int(delays[Int(rang)] / gcd)
for _ in 0..<frameCount {
frames.append(frame)
}
}
let animation = UIImage.animatedImage(with: frames,
duration: Double(duration) / 1000.0)
return animation
}
}
......@@ -156,6 +156,34 @@ extension UIImage {
return self.resizeImageWith(newSize: newSize)
}
func getNewSize(of size: CGSize) -> CGSize? {
if self.size.height == 0 {
return nil
}
var newWidth = size.width
var newHeight = size.height
let ratio = self.size.width / self.size.height
if ratio > 1 {
newHeight = newWidth / ratio
} else if ratio < 1, ratio != 0 {
// android image orientation bug?
if self.imageOrientation == UIImageOrientation.right ||
self.imageOrientation == UIImageOrientation.left ||
self.imageOrientation == UIImageOrientation.rightMirrored ||
self.imageOrientation == UIImageOrientation.leftMirrored {
newHeight *= ratio
} else {
newWidth = newHeight * ratio
}
}
let newSize = CGSize(width: newWidth, height: newHeight)
return newSize
}
func resizeImageWith(newSize: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(newSize, true, 0)
draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize))
......
......@@ -373,21 +373,37 @@ class MessageCell: UITableViewCell, NibReusable {
// swiftlint:enable function_body_length
func displayTransferedImage(message: MessageViewModel, conversationID: String) {
let maxDimsion: CGFloat = 250
let screenWidth = UIScreen.main.bounds.width
var maxDimsion: CGFloat = 250
//iPhone 5 width
if screenWidth <= 320 {
maxDimsion = 200
//iPhone 6, iPhone 6 Plus and iPhone XR width
} else if screenWidth > 320 && screenWidth <= 414 {
maxDimsion = 250
//iPad width
} else if screenWidth > 414 {
maxDimsion = 300
}
let defaultSize = CGSize(width: maxDimsion, height: maxDimsion)
if let image = message.getTransferedImage(maxSize: maxDimsion, conversationID: conversationID) {
self.transferImageView.image = image
self.transferImageView.contentMode = .center
let newSize = self.transferImageView.image?.getNewSize(of: defaultSize)
let xOriginImageSend = self.bubble.bounds.size.width - (newSize?.width)!
if message.bubblePosition() == .sent {
self.transferImageView.frame = CGRect(x: xOriginImageSend, y: 0, width: ((newSize?.width ?? 200)), height: ((newSize?.height ?? 200)))
} else if message.bubblePosition() == .received {
self.transferImageView.frame = CGRect(x: 0, y: 0, width: ((newSize?.width ?? 200)), height: ((newSize?.height ?? 200)))
}
self.transferImageView.layer.cornerRadius = 20
self.transferImageView.layer.masksToBounds = true
self.transferImageView.contentMode = .scaleAspectFill
buttonsHeightConstraint?.priority = UILayoutPriority(rawValue: 250.0)
self.bubble.addSubview(self.transferImageView)
self.bubbleViewMask?.isHidden = false
self.bottomCorner.isHidden = true
self.topCorner.isHidden = true
self.transferImageView.translatesAutoresizingMaskIntoConstraints = false
if message.bubblePosition() == .sent {
self.transferImageView.trailingAnchor.constraint(equalTo: self.bubble.trailingAnchor, constant: 0).isActive = true
} else if message.bubblePosition() == .received {
self.transferImageView.leadingAnchor.constraint(equalTo: self.bubble.leadingAnchor, constant: 0).isActive = true
}
self.transferImageView.translatesAutoresizingMaskIntoConstraints = true
self.transferImageView.topAnchor.constraint(equalTo: self.bubble.topAnchor, constant: 0).isActive = true
self.transferImageView.bottomAnchor.constraint(equalTo: self.bubble.bottomAnchor, constant: 0).isActive = true
}
......
......@@ -2,6 +2,13 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>LSApplicationCategoryType</key>
<string></string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
......
......@@ -178,10 +178,8 @@ public final class DataTransferService: DataTransferAdapterDelegate {
guard let asset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: PHFetchOptions()).firstObject else {
return photo
}
imageManager.requestImage(for: asset, targetSize: CGSize(width: maxSize, height: maxSize), contentMode: .aspectFit, options: requestOptions, resultHandler: {(result, _) -> Void in
let roundedImagemage = result?.setRoundCorner(radius: 20.0, offset: 1)
self.transferedImages[identifier] = (true, roundedImagemage)
photo = roundedImagemage
imageManager.requestImage(for: asset, targetSize: CGSize(width: maxSize, height: maxSize * 2), contentMode: .aspectFit, options: requestOptions, resultHandler: {(result, _) -> Void in
photo = result!
})
return photo
}
......@@ -200,11 +198,13 @@ public final class DataTransferService: DataTransferAdapterDelegate {
if UTTypeConformsTo(uti.takeRetainedValue(), kUTTypeImage) {
let fileManager = FileManager.default
if fileManager.fileExists(atPath: pathUrl.path) {
let image = UIImage(contentsOfFile: pathUrl.path)
let resizedImage = image?.resizeIntoRectangle(of: CGSize(width: maxSize, height: maxSize))
let roundedImage = resizedImage?.setRoundCorner(radius: 20.0, offset: 1)
self.transferedImages[conversationID + name] = (true, roundedImage)
return roundedImage
if fileExtension as String == "gif" {
let image = UIImage.gifImageWithUrl(pathUrl)
return image
} else {
let image = UIImage(contentsOfFile: pathUrl.path)
return image
}
}
} else {
self.transferedImages[conversationID + name] = (false, nil)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment