First Version of Blurit_SDK

This commit is contained in:
Bertrand VILLAIN 2021-11-30 19:00:22 +01:00
commit 2048654fb1
99 changed files with 4634 additions and 0 deletions

40
.gitignore vendored Normal file
View File

@ -0,0 +1,40 @@
# OS X
.DS_Store
# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa
# Bundler
.bundle
Carthage
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
# Note: if you ignore the Pods directory, make sure to uncomment
# `pod install` in .travis.yml
#
# Pods/
#project
Example/Podfile.lock
Example/Pods
Example/Facelytics.xcworkspace

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

25
Blurit.podspec Normal file
View File

@ -0,0 +1,25 @@
Pod::Spec.new do |spec|
spec.name = "Blurit"
spec.version = "1.0.0"
spec.summary = "Blurit is an SDK to anonymize pictures and videos containing faces and car plates."
spec.description = <<-DESC
Blurit is able to track multiple faces and then detect gender and age for each detected face.
DESC
spec.homepage = "https://Blurit.io"
spec.license = { :type => 'COMMERCIAL', :file => 'LICENSE.md'}
spec.author = { "Wassa" => "contact@wassa.io" }
#spec.source = { :http => 'https://github.com/wassafr/Blurit-ios/raw/master/Blurit_SDK.zip'}
spec.source = { :http => 'file:' + __dir__ + '/Blurit_SDK.zip' }
spec.platform = :ios, '13.0'
spec.swift_versions = '5.4'
spec.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
spec.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
spec.ios.vendored_frameworks = 'Blurit_SDK.xcframework'
spec.frameworks = 'Blurit'
end

BIN
Blurit_SDK.xcframework.zip Normal file

Binary file not shown.

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-x86_64-simulator</string>
<key>LibraryPath</key>
<string>Blurit_SDK.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>Blurit_SDK.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@ -0,0 +1,6 @@
# Changelog
All notable changes to this Framework will be documented in this file.
## [0.0.1] - BVI - 2021-09-21
- Project creation

View File

@ -0,0 +1,108 @@
# Blurit
[![Version](https://img.shields.io/cocoapods/v/Blurit?style=flat)](http://cocoapods.org/pods/Blurit)
[![License](https://img.shields.io/cocoapods/l/Blurit?style=flat)](http://cocoapods.org/pods/Blurit)
[![Platform](https://img.shields.io/cocoapods/p/Blurit?style=flat)](http://cocoapods.org/pods/Blurit)
<a href="https://swift.org/package-manager/"><img src="https://img.shields.io/badge/SPM-supported-Green.svg?style=flat"></a>
Blurit is an SDK to anonymize picture and videos containing faces and car plates.<br>
For more information about Blurit you can visit our [website](http://blurit.io/library/ios).
## Installation
### CocoaPods
[CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) is the recommended way to add Blurit to your project.
1. Add a pod entry for Blurit to your *Podfile* :
```
pod 'Blurit_SDK'
```
2. Install the pod(s) by running `pod install`.
3. Include Blurit wherever you need it with `#import <Blurit/Blurit.h>` from Objective-C or `import Blurit` from Swift.
### Swift Package Manager
```swift
dependencies: [
.package(url: "https://github.com/wassafr/Blurit-ios.git", from: "1.0.0")
]
```
### Manual installation
1. Download the [latest code version](https://github.com/wassafr/Blurit-ios/raw/master/Blurit.zip) or add the repository as a git submodule to your git-tracked project.
2. Include Blurit wherever you need it with `#import <Blurit_SDK/Blurit_SDK.h>` from Objective-C or `import Blurit_SDK` from Swift.
## Usage
To run the example project just open it and run. The framework is already included.
Make sure you also see [Blurit documentation](https://services.wassa.io/api/global-documentation/).
**Attention :** To use the SDK, you need a License Key you can get on the [Blurit website](http://blurit.io)
The sample code is commented and show usage examples of the SDK.
###Basics
1. Add the following import to the top of the file :
```
import Blurit
```
2. Instantiate a Blurit object
``
bluritInstance = Blurit(licenceKey: "your license key", completion: nil)
```
3. Load the detection models in the Blurit instance
```
bluritInstance?.loadModels(completion: { (error) in
if let error = error {
print("❌ Cannot initialize Blurit \(error.localizedDescription)")
} else {
}
})
```
4. Make prediction from picture
```
BluritService.shared.bluritInstance?.detectObjectsAsync(sourceImage: image, completion: { firstCompletionResult in
/// Handle detected objects
})
``````
5. You can now use prediction for gender and age
BluritService.shared.bluritInstance?.anonymizeAsync(sourceImage: image, predictionResult: predictionResult, completion: { secondCompletionResult in
/// Handle blurred picture
})
``````
## Requirements
- Xcode 13
- iOS 13
## License
Blurit is available under a commercial license. See the LICENSE file for more info.
## Author
Wassa, contact@wassa.fr

View File

@ -0,0 +1,214 @@
// Generated by Apple Swift version 5.5 (swiftlang-1300.0.31.1 clang-1300.0.29.1)
#ifndef BLURIT_SDK_SWIFT_H
#define BLURIT_SDK_SWIFT_H
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgcc-compat"
#if !defined(__has_include)
# define __has_include(x) 0
#endif
#if !defined(__has_attribute)
# define __has_attribute(x) 0
#endif
#if !defined(__has_feature)
# define __has_feature(x) 0
#endif
#if !defined(__has_warning)
# define __has_warning(x) 0
#endif
#if __has_include(<swift/objc-prologue.h>)
# include <swift/objc-prologue.h>
#endif
#pragma clang diagnostic ignored "-Wauto-import"
#include <Foundation/Foundation.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#if !defined(SWIFT_TYPEDEFS)
# define SWIFT_TYPEDEFS 1
# if __has_include(<uchar.h>)
# include <uchar.h>
# elif !defined(__cplusplus)
typedef uint_least16_t char16_t;
typedef uint_least32_t char32_t;
# endif
typedef float swift_float2 __attribute__((__ext_vector_type__(2)));
typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2)));
typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3)));
typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#endif
#if !defined(SWIFT_PASTE)
# define SWIFT_PASTE_HELPER(x, y) x##y
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
#endif
#if !defined(SWIFT_METATYPE)
# define SWIFT_METATYPE(X) Class
#endif
#if !defined(SWIFT_CLASS_PROPERTY)
# if __has_feature(objc_class_property)
# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
# else
# define SWIFT_CLASS_PROPERTY(...)
# endif
#endif
#if __has_attribute(objc_runtime_name)
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
#else
# define SWIFT_RUNTIME_NAME(X)
#endif
#if __has_attribute(swift_name)
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
#else
# define SWIFT_COMPILE_NAME(X)
#endif
#if __has_attribute(objc_method_family)
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
#else
# define SWIFT_METHOD_FAMILY(X)
#endif
#if __has_attribute(noescape)
# define SWIFT_NOESCAPE __attribute__((noescape))
#else
# define SWIFT_NOESCAPE
#endif
#if __has_attribute(ns_consumed)
# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed))
#else
# define SWIFT_RELEASES_ARGUMENT
#endif
#if __has_attribute(warn_unused_result)
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
# define SWIFT_WARN_UNUSED_RESULT
#endif
#if __has_attribute(noreturn)
# define SWIFT_NORETURN __attribute__((noreturn))
#else
# define SWIFT_NORETURN
#endif
#if !defined(SWIFT_CLASS_EXTRA)
# define SWIFT_CLASS_EXTRA
#endif
#if !defined(SWIFT_PROTOCOL_EXTRA)
# define SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_ENUM_EXTRA)
# define SWIFT_ENUM_EXTRA
#endif
#if !defined(SWIFT_CLASS)
# if __has_attribute(objc_subclassing_restricted)
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# else
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# endif
#endif
#if !defined(SWIFT_RESILIENT_CLASS)
# if __has_attribute(objc_class_stub)
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub))
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME)
# else
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME)
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME)
# endif
#endif
#if !defined(SWIFT_PROTOCOL)
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_EXTENSION)
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
#endif
#if !defined(OBJC_DESIGNATED_INITIALIZER)
# if __has_attribute(objc_designated_initializer)
# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
# else
# define OBJC_DESIGNATED_INITIALIZER
# endif
#endif
#if !defined(SWIFT_ENUM_ATTR)
# if defined(__has_attribute) && __has_attribute(enum_extensibility)
# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility)))
# else
# define SWIFT_ENUM_ATTR(_extensibility)
# endif
#endif
#if !defined(SWIFT_ENUM)
# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
# if __has_feature(generalized_swift_name)
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
# else
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility)
# endif
#endif
#if !defined(SWIFT_UNAVAILABLE)
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
#endif
#if !defined(SWIFT_UNAVAILABLE_MSG)
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
#endif
#if !defined(SWIFT_AVAILABILITY)
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
#endif
#if !defined(SWIFT_WEAK_IMPORT)
# define SWIFT_WEAK_IMPORT __attribute__((weak_import))
#endif
#if !defined(SWIFT_DEPRECATED)
# define SWIFT_DEPRECATED __attribute__((deprecated))
#endif
#if !defined(SWIFT_DEPRECATED_MSG)
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
#endif
#if __has_feature(attribute_diagnose_if_objc)
# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning")))
#else
# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)
#endif
#if !defined(IBSegueAction)
# define IBSegueAction
#endif
#if __has_feature(modules)
#if __has_warning("-Watimport-in-framework-header")
#pragma clang diagnostic ignored "-Watimport-in-framework-header"
#endif
#endif
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
#if __has_warning("-Wpragma-clang-attribute")
# pragma clang diagnostic ignored "-Wpragma-clang-attribute"
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wnullability"
#if __has_attribute(external_source_symbol)
# pragma push_macro("any")
# undef any
# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="Blurit_SDK",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol))
# pragma pop_macro("any")
#endif
#if __has_attribute(external_source_symbol)
# pragma clang attribute pop
#endif
#pragma clang diagnostic pop
#endif

View File

@ -0,0 +1,20 @@
//
// Blurit_SDK.h
// Blurit_SDK
//
// Created by Bertrand VILLAIN on 21/07/2021.
//
#import <Foundation/Foundation.h>
#include "LicenseKeyStatus.h"
#include "LicenseWrapper.h"
//! Project version number for Blurit.
FOUNDATION_EXPORT double BluritVersionNumber;
//! Project version string for Blurit.
FOUNDATION_EXPORT const unsigned char BluritVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <Blurit/PublicHeader.h>

View File

@ -0,0 +1,40 @@
//
// LicenseKeyStatus.h
// Blurit_SDK
//
// Created by Bertrand VILLAIN on 01/04/2019.
// Copyright © 2019 Wassa. All rights reserved.
//
#ifndef LICENSEKEYSTATUS_h
#define LICENSEKEYSTATUS_h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* The different possible status of your license key, if you have any problem with your license contact Pixlytics support
*/
typedef NS_ENUM(NSInteger, LicenseKeyStatus) {
///Your license is valid
LicenseOk,
///The format contained in your license is not valid
InvalidLicenseFormat,
///Your license has been modified and signature is not valid anymore
InvalidLicenseModified,
///Your license is no longer valid, date has expired
InvalidLicenseExpired,
///Your license is blocked because of unpayment
InvalidLicenseNotPaid,
///Your license is blocked
InvalidLicenseBlocked,
///The license could be valid but is not targeted for this library
LicenseIncorrectType,
///Other error
LicenseUnknownError
};
NS_ASSUME_NONNULL_END
#endif

View File

@ -0,0 +1,18 @@
//
// LicenseWrapper.h
// Blurit_SDK
//
// Created by Bertrand VILLAIN on 03/04/2019.
// Copyright © 2019 Wassa. All rights reserved.
//
#import <Foundation/Foundation.h>
#include "LicenseKeyStatus.h"
@interface LicenseWrapper : NSObject
- (instancetype _Nullable )initWithLicense:(NSString* _Nonnull) licenseKey libraryType:(NSString* _Nonnull)libraryType;
- (LicenseKeyStatus)getLicenseStatus;
- (void)updateLicense:(NSString* _Nonnull) licenseKey;
@end

View File

@ -0,0 +1,101 @@
// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 5.5 (swiftlang-1300.0.31.1 clang-1300.0.29.1)
// swift-module-flags: -target arm64-apple-ios13.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name Blurit_SDK
import AVFoundation
import Accelerate
@_exported import Blurit_SDK
import Compression
import CoreFoundation
import CoreML
import Foundation
import SpriteKit
import Swift
import UIKit
import _Concurrency
public typealias CRC32 = Swift.UInt32
public typealias Consumer = (_ data: Foundation.Data) throws -> Swift.Void
public typealias Provider = (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data
extension Foundation.Data {
public func crc32(checksum: Blurit_SDK.CRC32) -> Blurit_SDK.CRC32
public static func compress(size: Swift.Int, bufferSize: Swift.Int, provider: (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data, consumer: (_ data: Foundation.Data) throws -> Swift.Void) throws -> Blurit_SDK.CRC32
public static func decompress(size: Swift.Int, bufferSize: Swift.Int, skipCRC32: Swift.Bool, provider: (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data, consumer: (_ data: Foundation.Data) throws -> Swift.Void) throws -> Blurit_SDK.CRC32
}
extension Blurit_SDK.LicenseKeyStatus : Foundation.LocalizedError {
public var errorDescription: Swift.String? {
get
}
public static var _nsErrorDomain: Swift.String {
get
}
}
public struct DetectedElement {
public var rect: CoreGraphics.CGRect
public var objectType: Blurit_SDK.DetectedElement.DetectionType
public let confidenceRate: Swift.Float
public var frameIndex: Swift.Int?
public enum DetectionType {
case face
case plate
public static func == (a: Blurit_SDK.DetectedElement.DetectionType, b: Blurit_SDK.DetectedElement.DetectionType) -> Swift.Bool
public func hash(into hasher: inout Swift.Hasher)
public var hashValue: Swift.Int {
get
}
}
}
public struct VideoPredictionResult {
public var frameResultDict: [Swift.Int : Blurit_SDK.ImagePredictionResult]
public let frameNumber: Swift.Int
}
extension Foundation.FileManager {
public func unzipItem(at sourceURL: Foundation.URL, to destinationURL: Foundation.URL, skipCRC32: Swift.Bool = false, progress: Foundation.Progress? = nil, preferredEncoding: Swift.String.Encoding? = nil) throws
}
extension Foundation.URL {
public func isContained(in parentDirectoryURL: Foundation.URL) -> Swift.Bool
}
public let defaultReadChunkSize: Swift.UInt32
public let defaultWriteChunkSize: Swift.UInt32
public let defaultFilePermissions: Swift.UInt16
public let defaultDirectoryPermissions: Swift.UInt16
public struct BluritConfiguration {
public var strongThresholdScore: Swift.Float
public var weakThresholdScore: Swift.Float
public var maxFrameGapTracking: Swift.Int
public var numberOfFramesToSkip: Swift.Int
public var minTrackingFrameNumber: Swift.Int
}
public struct ImagePredictionResult {
public var detectedElements: [Blurit_SDK.DetectedElement]
}
public enum BluritError : Swift.Error {
case incorrectParameter(parameter: Swift.String, message: Swift.String?)
case failedToLoadModel
case modelNotLoaded
case modelAlreadyLoaded
case invalidLicense(licenseStatus: Blurit_SDK.LicenseKeyStatus)
case unableToProcessImage
case invalidVideoUrl
case incorrectVideo
}
extension Blurit_SDK.BluritError : Foundation.LocalizedError {
public var errorDescription: Swift.String? {
get
}
}
public class Blurit {
public init(licenceKey: Swift.String, completion: ((Swift.Error?) -> Swift.Void)?)
public func getLicense() -> Blurit_SDK.LicenseKeyStatus?
public func updateLicense(licenceKey: Swift.String) -> Blurit_SDK.LicenseKeyStatus?
public func loadModels(completion: ((Swift.Error?) -> Swift.Void)?)
public func detectObjectsAsync(videoUrl: Foundation.URL, completion: @escaping (Swift.Result<Blurit_SDK.VideoPredictionResult, Swift.Error>) -> Swift.Void)
public func detectObjectsSync(videoUrl: Foundation.URL) -> Swift.Result<Blurit_SDK.VideoPredictionResult, Swift.Error>
public func anonymizeAsync(videoUrl: Foundation.URL, predictionResult: Blurit_SDK.VideoPredictionResult, completion: @escaping (Swift.Result<Foundation.URL, Swift.Error>) -> Swift.Void)
public func anonymizeSync(videoUrl: Foundation.URL, predictionResult: Blurit_SDK.VideoPredictionResult) -> Swift.Result<Foundation.URL, Swift.Error>
public func detectObjectsAsync(sourceImage: UIKit.UIImage, completion: @escaping (Swift.Result<Blurit_SDK.ImagePredictionResult, Swift.Error>) -> Swift.Void)
public func detectObjectsSync(sourceImage: UIKit.UIImage) -> Swift.Result<Blurit_SDK.ImagePredictionResult, Swift.Error>
public func anonymizeAsync(sourceImage: UIKit.UIImage, predictionResult: Blurit_SDK.ImagePredictionResult, completion: @escaping (Swift.Result<UIKit.UIImage, Swift.Error>) -> Swift.Void)
public func anonymizeSync(sourceImage: UIKit.UIImage, predictionResult: Blurit_SDK.ImagePredictionResult) -> Swift.Result<UIKit.UIImage, Swift.Error>
@objc deinit
}
extension Blurit_SDK.DetectedElement.DetectionType : Swift.Equatable {}
extension Blurit_SDK.DetectedElement.DetectionType : Swift.Hashable {}

View File

@ -0,0 +1,101 @@
// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 5.5 (swiftlang-1300.0.31.1 clang-1300.0.29.1)
// swift-module-flags: -target arm64-apple-ios13.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name Blurit_SDK
import AVFoundation
import Accelerate
@_exported import Blurit_SDK
import Compression
import CoreFoundation
import CoreML
import Foundation
import SpriteKit
import Swift
import UIKit
import _Concurrency
public typealias CRC32 = Swift.UInt32
public typealias Consumer = (_ data: Foundation.Data) throws -> Swift.Void
public typealias Provider = (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data
extension Foundation.Data {
public func crc32(checksum: Blurit_SDK.CRC32) -> Blurit_SDK.CRC32
public static func compress(size: Swift.Int, bufferSize: Swift.Int, provider: (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data, consumer: (_ data: Foundation.Data) throws -> Swift.Void) throws -> Blurit_SDK.CRC32
public static func decompress(size: Swift.Int, bufferSize: Swift.Int, skipCRC32: Swift.Bool, provider: (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data, consumer: (_ data: Foundation.Data) throws -> Swift.Void) throws -> Blurit_SDK.CRC32
}
extension Blurit_SDK.LicenseKeyStatus : Foundation.LocalizedError {
public var errorDescription: Swift.String? {
get
}
public static var _nsErrorDomain: Swift.String {
get
}
}
public struct DetectedElement {
public var rect: CoreGraphics.CGRect
public var objectType: Blurit_SDK.DetectedElement.DetectionType
public let confidenceRate: Swift.Float
public var frameIndex: Swift.Int?
public enum DetectionType {
case face
case plate
public static func == (a: Blurit_SDK.DetectedElement.DetectionType, b: Blurit_SDK.DetectedElement.DetectionType) -> Swift.Bool
public func hash(into hasher: inout Swift.Hasher)
public var hashValue: Swift.Int {
get
}
}
}
public struct VideoPredictionResult {
public var frameResultDict: [Swift.Int : Blurit_SDK.ImagePredictionResult]
public let frameNumber: Swift.Int
}
extension Foundation.FileManager {
public func unzipItem(at sourceURL: Foundation.URL, to destinationURL: Foundation.URL, skipCRC32: Swift.Bool = false, progress: Foundation.Progress? = nil, preferredEncoding: Swift.String.Encoding? = nil) throws
}
extension Foundation.URL {
public func isContained(in parentDirectoryURL: Foundation.URL) -> Swift.Bool
}
public let defaultReadChunkSize: Swift.UInt32
public let defaultWriteChunkSize: Swift.UInt32
public let defaultFilePermissions: Swift.UInt16
public let defaultDirectoryPermissions: Swift.UInt16
public struct BluritConfiguration {
public var strongThresholdScore: Swift.Float
public var weakThresholdScore: Swift.Float
public var maxFrameGapTracking: Swift.Int
public var numberOfFramesToSkip: Swift.Int
public var minTrackingFrameNumber: Swift.Int
}
public struct ImagePredictionResult {
public var detectedElements: [Blurit_SDK.DetectedElement]
}
public enum BluritError : Swift.Error {
case incorrectParameter(parameter: Swift.String, message: Swift.String?)
case failedToLoadModel
case modelNotLoaded
case modelAlreadyLoaded
case invalidLicense(licenseStatus: Blurit_SDK.LicenseKeyStatus)
case unableToProcessImage
case invalidVideoUrl
case incorrectVideo
}
extension Blurit_SDK.BluritError : Foundation.LocalizedError {
public var errorDescription: Swift.String? {
get
}
}
public class Blurit {
public init(licenceKey: Swift.String, completion: ((Swift.Error?) -> Swift.Void)?)
public func getLicense() -> Blurit_SDK.LicenseKeyStatus?
public func updateLicense(licenceKey: Swift.String) -> Blurit_SDK.LicenseKeyStatus?
public func loadModels(completion: ((Swift.Error?) -> Swift.Void)?)
public func detectObjectsAsync(videoUrl: Foundation.URL, completion: @escaping (Swift.Result<Blurit_SDK.VideoPredictionResult, Swift.Error>) -> Swift.Void)
public func detectObjectsSync(videoUrl: Foundation.URL) -> Swift.Result<Blurit_SDK.VideoPredictionResult, Swift.Error>
public func anonymizeAsync(videoUrl: Foundation.URL, predictionResult: Blurit_SDK.VideoPredictionResult, completion: @escaping (Swift.Result<Foundation.URL, Swift.Error>) -> Swift.Void)
public func anonymizeSync(videoUrl: Foundation.URL, predictionResult: Blurit_SDK.VideoPredictionResult) -> Swift.Result<Foundation.URL, Swift.Error>
public func detectObjectsAsync(sourceImage: UIKit.UIImage, completion: @escaping (Swift.Result<Blurit_SDK.ImagePredictionResult, Swift.Error>) -> Swift.Void)
public func detectObjectsSync(sourceImage: UIKit.UIImage) -> Swift.Result<Blurit_SDK.ImagePredictionResult, Swift.Error>
public func anonymizeAsync(sourceImage: UIKit.UIImage, predictionResult: Blurit_SDK.ImagePredictionResult, completion: @escaping (Swift.Result<UIKit.UIImage, Swift.Error>) -> Swift.Void)
public func anonymizeSync(sourceImage: UIKit.UIImage, predictionResult: Blurit_SDK.ImagePredictionResult) -> Swift.Result<UIKit.UIImage, Swift.Error>
@objc deinit
}
extension Blurit_SDK.DetectedElement.DetectionType : Swift.Equatable {}
extension Blurit_SDK.DetectedElement.DetectionType : Swift.Hashable {}

View File

@ -0,0 +1,11 @@
framework module Blurit_SDK {
umbrella header "Blurit_SDK.h"
export *
module * { export * }
}
module Blurit_SDK.Swift {
header "Blurit_SDK-Swift.h"
requires objc
}

View File

@ -0,0 +1,58 @@
# Blurit SDK
## Synopsis
## Environment setup & installation
- XCode 12.0+
- iOS 13.0+
⚠️ Use `git clone --recurse-submodules -j8` ⚠️
You can use the framework directly, no specific install to make.
The framework and its dependencies are automatically compilled when you Build & Run the sampleProject.
## Framework creation
To distribute Blurit in a framework through Swift Package Manager we have to create an xcframework
To generate the XCFramework just run the scheme GenerateXCFramework and recover the result in the folder Blurit-Frameworks/, then put the folder Blurit_SDK.xcframework into the proper place to deploy it for Cocoapod and SPM.
⚠️ In the case you face an issue with the generation you can check the script at GenerateBluritXCFramework.sh.
## External dependencies
- ZIPFoundation
- CoreFoundation
- Foundation
- CoreML
- MetalPetal
- VideoIO
![Dependencies](Blurit_iOS_architecture_and_dependencies.png)
### Other dependencies
- ZIPFoundation
- MobileLicenseSystem (libcryptopp)
## CPU Architectures
- arm64 arm64e i386 are the only valid architectures
- armv7 armv7s are not supported by this framework as iOS 12 (needed for CoreML) doesn't support those architectures, so it is useless to implement them.
## Documentation 📑
We use Jazzy to generate html doc (sudo gem install jazzy)
Just run the command `jazzy .jazzy.yaml` in the terminal to generate the documentation (Swift only ⚠️)
The details of the parameters used for jazzy are located in the file .jazzy.yml
OR
`brew install sourcekitten`
To generate a mixed version from Obj C and Swift use the following script `./generatedoc.sh`
## License
Blurit is available under a commercial license. The license file is located in the Blurit pod repo.
## Author
Wassa, contact@wassa.io

View File

@ -0,0 +1,6 @@
# Changelog
All notable changes to this Framework will be documented in this file.
## [0.0.1] - BVI - 2021-09-21
- Project creation

View File

@ -0,0 +1,108 @@
# Blurit
[![Version](https://img.shields.io/cocoapods/v/Blurit?style=flat)](http://cocoapods.org/pods/Blurit)
[![License](https://img.shields.io/cocoapods/l/Blurit?style=flat)](http://cocoapods.org/pods/Blurit)
[![Platform](https://img.shields.io/cocoapods/p/Blurit?style=flat)](http://cocoapods.org/pods/Blurit)
<a href="https://swift.org/package-manager/"><img src="https://img.shields.io/badge/SPM-supported-Green.svg?style=flat"></a>
Blurit is an SDK to anonymize picture and videos containing faces and car plates.<br>
For more information about Blurit you can visit our [website](http://blurit.io/library/ios).
## Installation
### CocoaPods
[CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) is the recommended way to add Blurit to your project.
1. Add a pod entry for Blurit to your *Podfile* :
```
pod 'Blurit_SDK'
```
2. Install the pod(s) by running `pod install`.
3. Include Blurit wherever you need it with `#import <Blurit/Blurit.h>` from Objective-C or `import Blurit` from Swift.
### Swift Package Manager
```swift
dependencies: [
.package(url: "https://github.com/wassafr/Blurit-ios.git", from: "1.0.0")
]
```
### Manual installation
1. Download the [latest code version](https://github.com/wassafr/Blurit-ios/raw/master/Blurit.zip) or add the repository as a git submodule to your git-tracked project.
2. Include Blurit wherever you need it with `#import <Blurit_SDK/Blurit_SDK.h>` from Objective-C or `import Blurit_SDK` from Swift.
## Usage
To run the example project just open it and run. The framework is already included.
Make sure you also see [Blurit documentation](https://services.wassa.io/api/global-documentation/).
**Attention :** To use the SDK, you need a License Key you can get on the [Blurit website](http://blurit.io)
The sample code is commented and show usage examples of the SDK.
###Basics
1. Add the following import to the top of the file :
```
import Blurit
```
2. Instantiate a Blurit object
``
bluritInstance = Blurit(licenceKey: "your license key", completion: nil)
```
3. Load the detection models in the Blurit instance
```
bluritInstance?.loadModels(completion: { (error) in
if let error = error {
print("❌ Cannot initialize Blurit \(error.localizedDescription)")
} else {
}
})
```
4. Make prediction from picture
```
BluritService.shared.bluritInstance?.detectObjectsAsync(sourceImage: image, completion: { firstCompletionResult in
/// Handle detected objects
})
``````
5. You can now use prediction for gender and age
BluritService.shared.bluritInstance?.anonymizeAsync(sourceImage: image, predictionResult: predictionResult, completion: { secondCompletionResult in
/// Handle blurred picture
})
``````
## Requirements
- Xcode 13
- iOS 13
## License
Blurit is available under a commercial license. See the LICENSE file for more info.
## Author
Wassa, contact@wassa.fr

View File

@ -0,0 +1,214 @@
// Generated by Apple Swift version 5.5 (swiftlang-1300.0.31.1 clang-1300.0.29.1)
#ifndef BLURIT_SDK_SWIFT_H
#define BLURIT_SDK_SWIFT_H
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgcc-compat"
#if !defined(__has_include)
# define __has_include(x) 0
#endif
#if !defined(__has_attribute)
# define __has_attribute(x) 0
#endif
#if !defined(__has_feature)
# define __has_feature(x) 0
#endif
#if !defined(__has_warning)
# define __has_warning(x) 0
#endif
#if __has_include(<swift/objc-prologue.h>)
# include <swift/objc-prologue.h>
#endif
#pragma clang diagnostic ignored "-Wauto-import"
#include <Foundation/Foundation.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#if !defined(SWIFT_TYPEDEFS)
# define SWIFT_TYPEDEFS 1
# if __has_include(<uchar.h>)
# include <uchar.h>
# elif !defined(__cplusplus)
typedef uint_least16_t char16_t;
typedef uint_least32_t char32_t;
# endif
typedef float swift_float2 __attribute__((__ext_vector_type__(2)));
typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2)));
typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3)));
typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#endif
#if !defined(SWIFT_PASTE)
# define SWIFT_PASTE_HELPER(x, y) x##y
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
#endif
#if !defined(SWIFT_METATYPE)
# define SWIFT_METATYPE(X) Class
#endif
#if !defined(SWIFT_CLASS_PROPERTY)
# if __has_feature(objc_class_property)
# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
# else
# define SWIFT_CLASS_PROPERTY(...)
# endif
#endif
#if __has_attribute(objc_runtime_name)
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
#else
# define SWIFT_RUNTIME_NAME(X)
#endif
#if __has_attribute(swift_name)
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
#else
# define SWIFT_COMPILE_NAME(X)
#endif
#if __has_attribute(objc_method_family)
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
#else
# define SWIFT_METHOD_FAMILY(X)
#endif
#if __has_attribute(noescape)
# define SWIFT_NOESCAPE __attribute__((noescape))
#else
# define SWIFT_NOESCAPE
#endif
#if __has_attribute(ns_consumed)
# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed))
#else
# define SWIFT_RELEASES_ARGUMENT
#endif
#if __has_attribute(warn_unused_result)
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
# define SWIFT_WARN_UNUSED_RESULT
#endif
#if __has_attribute(noreturn)
# define SWIFT_NORETURN __attribute__((noreturn))
#else
# define SWIFT_NORETURN
#endif
#if !defined(SWIFT_CLASS_EXTRA)
# define SWIFT_CLASS_EXTRA
#endif
#if !defined(SWIFT_PROTOCOL_EXTRA)
# define SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_ENUM_EXTRA)
# define SWIFT_ENUM_EXTRA
#endif
#if !defined(SWIFT_CLASS)
# if __has_attribute(objc_subclassing_restricted)
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# else
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# endif
#endif
#if !defined(SWIFT_RESILIENT_CLASS)
# if __has_attribute(objc_class_stub)
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub))
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME)
# else
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME)
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME)
# endif
#endif
#if !defined(SWIFT_PROTOCOL)
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_EXTENSION)
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
#endif
#if !defined(OBJC_DESIGNATED_INITIALIZER)
# if __has_attribute(objc_designated_initializer)
# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
# else
# define OBJC_DESIGNATED_INITIALIZER
# endif
#endif
#if !defined(SWIFT_ENUM_ATTR)
# if defined(__has_attribute) && __has_attribute(enum_extensibility)
# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility)))
# else
# define SWIFT_ENUM_ATTR(_extensibility)
# endif
#endif
#if !defined(SWIFT_ENUM)
# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
# if __has_feature(generalized_swift_name)
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
# else
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility)
# endif
#endif
#if !defined(SWIFT_UNAVAILABLE)
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
#endif
#if !defined(SWIFT_UNAVAILABLE_MSG)
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
#endif
#if !defined(SWIFT_AVAILABILITY)
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
#endif
#if !defined(SWIFT_WEAK_IMPORT)
# define SWIFT_WEAK_IMPORT __attribute__((weak_import))
#endif
#if !defined(SWIFT_DEPRECATED)
# define SWIFT_DEPRECATED __attribute__((deprecated))
#endif
#if !defined(SWIFT_DEPRECATED_MSG)
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
#endif
#if __has_feature(attribute_diagnose_if_objc)
# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning")))
#else
# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)
#endif
#if !defined(IBSegueAction)
# define IBSegueAction
#endif
#if __has_feature(modules)
#if __has_warning("-Watimport-in-framework-header")
#pragma clang diagnostic ignored "-Watimport-in-framework-header"
#endif
#endif
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
#if __has_warning("-Wpragma-clang-attribute")
# pragma clang diagnostic ignored "-Wpragma-clang-attribute"
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wnullability"
#if __has_attribute(external_source_symbol)
# pragma push_macro("any")
# undef any
# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="Blurit_SDK",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol))
# pragma pop_macro("any")
#endif
#if __has_attribute(external_source_symbol)
# pragma clang attribute pop
#endif
#pragma clang diagnostic pop
#endif

View File

@ -0,0 +1,20 @@
//
// Blurit_SDK.h
// Blurit_SDK
//
// Created by Bertrand VILLAIN on 21/07/2021.
//
#import <Foundation/Foundation.h>
#include "LicenseKeyStatus.h"
#include "LicenseWrapper.h"
//! Project version number for Blurit.
FOUNDATION_EXPORT double BluritVersionNumber;
//! Project version string for Blurit.
FOUNDATION_EXPORT const unsigned char BluritVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <Blurit/PublicHeader.h>

View File

@ -0,0 +1,40 @@
//
// LicenseKeyStatus.h
// Blurit_SDK
//
// Created by Bertrand VILLAIN on 01/04/2019.
// Copyright © 2019 Wassa. All rights reserved.
//
#ifndef LICENSEKEYSTATUS_h
#define LICENSEKEYSTATUS_h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* The different possible status of your license key, if you have any problem with your license contact Pixlytics support
*/
typedef NS_ENUM(NSInteger, LicenseKeyStatus) {
///Your license is valid
LicenseOk,
///The format contained in your license is not valid
InvalidLicenseFormat,
///Your license has been modified and signature is not valid anymore
InvalidLicenseModified,
///Your license is no longer valid, date has expired
InvalidLicenseExpired,
///Your license is blocked because of unpayment
InvalidLicenseNotPaid,
///Your license is blocked
InvalidLicenseBlocked,
///The license could be valid but is not targeted for this library
LicenseIncorrectType,
///Other error
LicenseUnknownError
};
NS_ASSUME_NONNULL_END
#endif

View File

@ -0,0 +1,18 @@
//
// LicenseWrapper.h
// Blurit_SDK
//
// Created by Bertrand VILLAIN on 03/04/2019.
// Copyright © 2019 Wassa. All rights reserved.
//
#import <Foundation/Foundation.h>
#include "LicenseKeyStatus.h"
@interface LicenseWrapper : NSObject
- (instancetype _Nullable )initWithLicense:(NSString* _Nonnull) licenseKey libraryType:(NSString* _Nonnull)libraryType;
- (LicenseKeyStatus)getLicenseStatus;
- (void)updateLicense:(NSString* _Nonnull) licenseKey;
@end

View File

@ -0,0 +1,101 @@
// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 5.5 (swiftlang-1300.0.31.1 clang-1300.0.29.1)
// swift-module-flags: -target x86_64-apple-ios13.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name Blurit_SDK
import AVFoundation
import Accelerate
@_exported import Blurit_SDK
import Compression
import CoreFoundation
import CoreML
import Foundation
import SpriteKit
import Swift
import UIKit
import _Concurrency
public typealias CRC32 = Swift.UInt32
public typealias Consumer = (_ data: Foundation.Data) throws -> Swift.Void
public typealias Provider = (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data
extension Foundation.Data {
public func crc32(checksum: Blurit_SDK.CRC32) -> Blurit_SDK.CRC32
public static func compress(size: Swift.Int, bufferSize: Swift.Int, provider: (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data, consumer: (_ data: Foundation.Data) throws -> Swift.Void) throws -> Blurit_SDK.CRC32
public static func decompress(size: Swift.Int, bufferSize: Swift.Int, skipCRC32: Swift.Bool, provider: (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data, consumer: (_ data: Foundation.Data) throws -> Swift.Void) throws -> Blurit_SDK.CRC32
}
extension Blurit_SDK.LicenseKeyStatus : Foundation.LocalizedError {
public var errorDescription: Swift.String? {
get
}
public static var _nsErrorDomain: Swift.String {
get
}
}
public struct DetectedElement {
public var rect: CoreGraphics.CGRect
public var objectType: Blurit_SDK.DetectedElement.DetectionType
public let confidenceRate: Swift.Float
public var frameIndex: Swift.Int?
public enum DetectionType {
case face
case plate
public static func == (a: Blurit_SDK.DetectedElement.DetectionType, b: Blurit_SDK.DetectedElement.DetectionType) -> Swift.Bool
public func hash(into hasher: inout Swift.Hasher)
public var hashValue: Swift.Int {
get
}
}
}
public struct VideoPredictionResult {
public var frameResultDict: [Swift.Int : Blurit_SDK.ImagePredictionResult]
public let frameNumber: Swift.Int
}
extension Foundation.FileManager {
public func unzipItem(at sourceURL: Foundation.URL, to destinationURL: Foundation.URL, skipCRC32: Swift.Bool = false, progress: Foundation.Progress? = nil, preferredEncoding: Swift.String.Encoding? = nil) throws
}
extension Foundation.URL {
public func isContained(in parentDirectoryURL: Foundation.URL) -> Swift.Bool
}
public let defaultReadChunkSize: Swift.UInt32
public let defaultWriteChunkSize: Swift.UInt32
public let defaultFilePermissions: Swift.UInt16
public let defaultDirectoryPermissions: Swift.UInt16
public struct BluritConfiguration {
public var strongThresholdScore: Swift.Float
public var weakThresholdScore: Swift.Float
public var maxFrameGapTracking: Swift.Int
public var numberOfFramesToSkip: Swift.Int
public var minTrackingFrameNumber: Swift.Int
}
public struct ImagePredictionResult {
public var detectedElements: [Blurit_SDK.DetectedElement]
}
public enum BluritError : Swift.Error {
case incorrectParameter(parameter: Swift.String, message: Swift.String?)
case failedToLoadModel
case modelNotLoaded
case modelAlreadyLoaded
case invalidLicense(licenseStatus: Blurit_SDK.LicenseKeyStatus)
case unableToProcessImage
case invalidVideoUrl
case incorrectVideo
}
extension Blurit_SDK.BluritError : Foundation.LocalizedError {
public var errorDescription: Swift.String? {
get
}
}
public class Blurit {
public init(licenceKey: Swift.String, completion: ((Swift.Error?) -> Swift.Void)?)
public func getLicense() -> Blurit_SDK.LicenseKeyStatus?
public func updateLicense(licenceKey: Swift.String) -> Blurit_SDK.LicenseKeyStatus?
public func loadModels(completion: ((Swift.Error?) -> Swift.Void)?)
public func detectObjectsAsync(videoUrl: Foundation.URL, completion: @escaping (Swift.Result<Blurit_SDK.VideoPredictionResult, Swift.Error>) -> Swift.Void)
public func detectObjectsSync(videoUrl: Foundation.URL) -> Swift.Result<Blurit_SDK.VideoPredictionResult, Swift.Error>
public func anonymizeAsync(videoUrl: Foundation.URL, predictionResult: Blurit_SDK.VideoPredictionResult, completion: @escaping (Swift.Result<Foundation.URL, Swift.Error>) -> Swift.Void)
public func anonymizeSync(videoUrl: Foundation.URL, predictionResult: Blurit_SDK.VideoPredictionResult) -> Swift.Result<Foundation.URL, Swift.Error>
public func detectObjectsAsync(sourceImage: UIKit.UIImage, completion: @escaping (Swift.Result<Blurit_SDK.ImagePredictionResult, Swift.Error>) -> Swift.Void)
public func detectObjectsSync(sourceImage: UIKit.UIImage) -> Swift.Result<Blurit_SDK.ImagePredictionResult, Swift.Error>
public func anonymizeAsync(sourceImage: UIKit.UIImage, predictionResult: Blurit_SDK.ImagePredictionResult, completion: @escaping (Swift.Result<UIKit.UIImage, Swift.Error>) -> Swift.Void)
public func anonymizeSync(sourceImage: UIKit.UIImage, predictionResult: Blurit_SDK.ImagePredictionResult) -> Swift.Result<UIKit.UIImage, Swift.Error>
@objc deinit
}
extension Blurit_SDK.DetectedElement.DetectionType : Swift.Equatable {}
extension Blurit_SDK.DetectedElement.DetectionType : Swift.Hashable {}

View File

@ -0,0 +1,101 @@
// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 5.5 (swiftlang-1300.0.31.1 clang-1300.0.29.1)
// swift-module-flags: -target x86_64-apple-ios13.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name Blurit_SDK
import AVFoundation
import Accelerate
@_exported import Blurit_SDK
import Compression
import CoreFoundation
import CoreML
import Foundation
import SpriteKit
import Swift
import UIKit
import _Concurrency
public typealias CRC32 = Swift.UInt32
public typealias Consumer = (_ data: Foundation.Data) throws -> Swift.Void
public typealias Provider = (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data
extension Foundation.Data {
public func crc32(checksum: Blurit_SDK.CRC32) -> Blurit_SDK.CRC32
public static func compress(size: Swift.Int, bufferSize: Swift.Int, provider: (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data, consumer: (_ data: Foundation.Data) throws -> Swift.Void) throws -> Blurit_SDK.CRC32
public static func decompress(size: Swift.Int, bufferSize: Swift.Int, skipCRC32: Swift.Bool, provider: (_ position: Swift.Int, _ size: Swift.Int) throws -> Foundation.Data, consumer: (_ data: Foundation.Data) throws -> Swift.Void) throws -> Blurit_SDK.CRC32
}
extension Blurit_SDK.LicenseKeyStatus : Foundation.LocalizedError {
public var errorDescription: Swift.String? {
get
}
public static var _nsErrorDomain: Swift.String {
get
}
}
public struct DetectedElement {
public var rect: CoreGraphics.CGRect
public var objectType: Blurit_SDK.DetectedElement.DetectionType
public let confidenceRate: Swift.Float
public var frameIndex: Swift.Int?
public enum DetectionType {
case face
case plate
public static func == (a: Blurit_SDK.DetectedElement.DetectionType, b: Blurit_SDK.DetectedElement.DetectionType) -> Swift.Bool
public func hash(into hasher: inout Swift.Hasher)
public var hashValue: Swift.Int {
get
}
}
}
public struct VideoPredictionResult {
public var frameResultDict: [Swift.Int : Blurit_SDK.ImagePredictionResult]
public let frameNumber: Swift.Int
}
extension Foundation.FileManager {
public func unzipItem(at sourceURL: Foundation.URL, to destinationURL: Foundation.URL, skipCRC32: Swift.Bool = false, progress: Foundation.Progress? = nil, preferredEncoding: Swift.String.Encoding? = nil) throws
}
extension Foundation.URL {
public func isContained(in parentDirectoryURL: Foundation.URL) -> Swift.Bool
}
public let defaultReadChunkSize: Swift.UInt32
public let defaultWriteChunkSize: Swift.UInt32
public let defaultFilePermissions: Swift.UInt16
public let defaultDirectoryPermissions: Swift.UInt16
public struct BluritConfiguration {
public var strongThresholdScore: Swift.Float
public var weakThresholdScore: Swift.Float
public var maxFrameGapTracking: Swift.Int
public var numberOfFramesToSkip: Swift.Int
public var minTrackingFrameNumber: Swift.Int
}
public struct ImagePredictionResult {
public var detectedElements: [Blurit_SDK.DetectedElement]
}
public enum BluritError : Swift.Error {
case incorrectParameter(parameter: Swift.String, message: Swift.String?)
case failedToLoadModel
case modelNotLoaded
case modelAlreadyLoaded
case invalidLicense(licenseStatus: Blurit_SDK.LicenseKeyStatus)
case unableToProcessImage
case invalidVideoUrl
case incorrectVideo
}
extension Blurit_SDK.BluritError : Foundation.LocalizedError {
public var errorDescription: Swift.String? {
get
}
}
public class Blurit {
public init(licenceKey: Swift.String, completion: ((Swift.Error?) -> Swift.Void)?)
public func getLicense() -> Blurit_SDK.LicenseKeyStatus?
public func updateLicense(licenceKey: Swift.String) -> Blurit_SDK.LicenseKeyStatus?
public func loadModels(completion: ((Swift.Error?) -> Swift.Void)?)
public func detectObjectsAsync(videoUrl: Foundation.URL, completion: @escaping (Swift.Result<Blurit_SDK.VideoPredictionResult, Swift.Error>) -> Swift.Void)
public func detectObjectsSync(videoUrl: Foundation.URL) -> Swift.Result<Blurit_SDK.VideoPredictionResult, Swift.Error>
public func anonymizeAsync(videoUrl: Foundation.URL, predictionResult: Blurit_SDK.VideoPredictionResult, completion: @escaping (Swift.Result<Foundation.URL, Swift.Error>) -> Swift.Void)
public func anonymizeSync(videoUrl: Foundation.URL, predictionResult: Blurit_SDK.VideoPredictionResult) -> Swift.Result<Foundation.URL, Swift.Error>
public func detectObjectsAsync(sourceImage: UIKit.UIImage, completion: @escaping (Swift.Result<Blurit_SDK.ImagePredictionResult, Swift.Error>) -> Swift.Void)
public func detectObjectsSync(sourceImage: UIKit.UIImage) -> Swift.Result<Blurit_SDK.ImagePredictionResult, Swift.Error>
public func anonymizeAsync(sourceImage: UIKit.UIImage, predictionResult: Blurit_SDK.ImagePredictionResult, completion: @escaping (Swift.Result<UIKit.UIImage, Swift.Error>) -> Swift.Void)
public func anonymizeSync(sourceImage: UIKit.UIImage, predictionResult: Blurit_SDK.ImagePredictionResult) -> Swift.Result<UIKit.UIImage, Swift.Error>
@objc deinit
}
extension Blurit_SDK.DetectedElement.DetectionType : Swift.Equatable {}
extension Blurit_SDK.DetectedElement.DetectionType : Swift.Hashable {}

View File

@ -0,0 +1,11 @@
framework module Blurit_SDK {
umbrella header "Blurit_SDK.h"
export *
module * { export * }
}
module Blurit_SDK.Swift {
header "Blurit_SDK-Swift.h"
requires objc
}

View File

@ -0,0 +1,58 @@
# Blurit SDK
## Synopsis
## Environment setup & installation
- XCode 12.0+
- iOS 13.0+
⚠️ Use `git clone --recurse-submodules -j8` ⚠️
You can use the framework directly, no specific install to make.
The framework and its dependencies are automatically compilled when you Build & Run the sampleProject.
## Framework creation
To distribute Blurit in a framework through Swift Package Manager we have to create an xcframework
To generate the XCFramework just run the scheme GenerateXCFramework and recover the result in the folder Blurit-Frameworks/, then put the folder Blurit_SDK.xcframework into the proper place to deploy it for Cocoapod and SPM.
⚠️ In the case you face an issue with the generation you can check the script at GenerateBluritXCFramework.sh.
## External dependencies
- ZIPFoundation
- CoreFoundation
- Foundation
- CoreML
- MetalPetal
- VideoIO
![Dependencies](Blurit_iOS_architecture_and_dependencies.png)
### Other dependencies
- ZIPFoundation
- MobileLicenseSystem (libcryptopp)
## CPU Architectures
- arm64 arm64e i386 are the only valid architectures
- armv7 armv7s are not supported by this framework as iOS 12 (needed for CoreML) doesn't support those architectures, so it is useless to implement them.
## Documentation 📑
We use Jazzy to generate html doc (sudo gem install jazzy)
Just run the command `jazzy .jazzy.yaml` in the terminal to generate the documentation (Swift only ⚠️)
The details of the parameters used for jazzy are located in the file .jazzy.yml
OR
`brew install sourcekitten`
To generate a mixed version from Obj C and Swift use the following script `./generatedoc.sh`
## License
Blurit is available under a commercial license. The license file is located in the Blurit pod repo.
## Author
Wassa, contact@wassa.io

View File

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Blurit_1280.zip</key>
<data>
tqAPIlpCj2eNRtstuoEGRChYY9g=
</data>
<key>Blurit_640.zip</key>
<data>
vRZNH6n09wKaEjAE4cNO2ePIGlY=
</data>
<key>CHANGELOG.md</key>
<data>
YeexJ6HaeuBbWLbpb1EZfbRWPSU=
</data>
<key>EXTERNALREADME.md</key>
<data>
qiqMUC7VDUyxNOmRbmnIiDD/xr4=
</data>
<key>Headers/Blurit_SDK-Swift.h</key>
<data>
z1g/FH+jWZRAtled55acXsqOLCs=
</data>
<key>Headers/Blurit_SDK.h</key>
<data>
q0YVl7Mj2hHl8b2X1fhIdN5LrsA=
</data>
<key>Headers/LicenseKeyStatus.h</key>
<data>
PVaZJ88dN3UdJocXfmtVXqwDXBw=
</data>
<key>Headers/LicenseWrapper.h</key>
<data>
wDfMFSiKSkLk1+UTl3FIsCGzfQM=
</data>
<key>Info.plist</key>
<data>
RaRnrmBMI51rffOdhMcXC2Gn4qw=
</data>
<key>Modules/Blurit_SDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc</key>
<data>
cwJd9LRA0nKVUrvd+6kd/v3pwck=
</data>
<key>Modules/Blurit_SDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface</key>
<data>
P87aa/K5bQoijkIKD+8uqjhOxkU=
</data>
<key>Modules/Blurit_SDK.swiftmodule/x86_64-apple-ios-simulator.swiftmodule</key>
<data>
j/RZYbhdFOvfluzJfs9uXaHNvjQ=
</data>
<key>Modules/Blurit_SDK.swiftmodule/x86_64.swiftdoc</key>
<data>
cwJd9LRA0nKVUrvd+6kd/v3pwck=
</data>
<key>Modules/Blurit_SDK.swiftmodule/x86_64.swiftinterface</key>
<data>
P87aa/K5bQoijkIKD+8uqjhOxkU=
</data>
<key>Modules/Blurit_SDK.swiftmodule/x86_64.swiftmodule</key>
<data>
j/RZYbhdFOvfluzJfs9uXaHNvjQ=
</data>
<key>Modules/module.modulemap</key>
<data>
wYXDJsurP3OTHLNKaD9/DoHCkYQ=
</data>
<key>README.md</key>
<data>
iRvHzDk5bbZ29Y+KastZYxOkgao=
</data>
</dict>
<key>files2</key>
<dict>
<key>Blurit_1280.zip</key>
<dict>
<key>hash2</key>
<data>
5p+da9VJhANHPFQQiKkvIhWZmgnE28ucKipEJH3d2Kw=
</data>
</dict>
<key>Blurit_640.zip</key>
<dict>
<key>hash2</key>
<data>
cXu0G32MmKWmP4U7blfhFzLql8mfwBL2se3cdVbnX6U=
</data>
</dict>
<key>CHANGELOG.md</key>
<dict>
<key>hash2</key>
<data>
mE+qlFC4ZlxqZWNCXjv0q6bPvW5nnHPKm9CZPDp1Fls=
</data>
</dict>
<key>EXTERNALREADME.md</key>
<dict>
<key>hash2</key>
<data>
7KPZVn/UXpZgRCTWO+Eg4vQLSHsdaFFbfbEwDlunQ3o=
</data>
</dict>
<key>Headers/Blurit_SDK-Swift.h</key>
<dict>
<key>hash2</key>
<data>
sw9+r5X0zbFx7IfUKZrJeVFpDrw20ePeJ6Pbuna+RSA=
</data>
</dict>
<key>Headers/Blurit_SDK.h</key>
<dict>
<key>hash2</key>
<data>
dAGrFwP0oBO2Ky8n/rRhGR6HUfeYHn1XkGxpt/UxDhk=
</data>
</dict>
<key>Headers/LicenseKeyStatus.h</key>
<dict>
<key>hash2</key>
<data>
aeHRQBrdEdTDba038RnKX8NK/dSReWmuN7j9cVCD6oY=
</data>
</dict>
<key>Headers/LicenseWrapper.h</key>
<dict>
<key>hash2</key>
<data>
fWIUpu6pb1NEwoNyPLMi0fQ2NBGi0dPT3stBuWl/qAI=
</data>
</dict>
<key>Modules/Blurit_SDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc</key>
<dict>
<key>hash2</key>
<data>
5FnTuZZ4AQc6/Z7p/F5pENZYP5HT0+ewGfefdyia2wo=
</data>
</dict>
<key>Modules/Blurit_SDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface</key>
<dict>
<key>hash2</key>
<data>
YLaPQESWbbPdD8tk82Kh8zfO6kebsheK1uM1eGv8avk=
</data>
</dict>
<key>Modules/Blurit_SDK.swiftmodule/x86_64-apple-ios-simulator.swiftmodule</key>
<dict>
<key>hash2</key>
<data>
3c9ySZmIlwDKytG5fZJdG7935xyazWWJyynK8quXFog=
</data>
</dict>
<key>Modules/Blurit_SDK.swiftmodule/x86_64.swiftdoc</key>
<dict>
<key>hash2</key>
<data>
5FnTuZZ4AQc6/Z7p/F5pENZYP5HT0+ewGfefdyia2wo=
</data>
</dict>
<key>Modules/Blurit_SDK.swiftmodule/x86_64.swiftinterface</key>
<dict>
<key>hash2</key>
<data>
YLaPQESWbbPdD8tk82Kh8zfO6kebsheK1uM1eGv8avk=
</data>
</dict>
<key>Modules/Blurit_SDK.swiftmodule/x86_64.swiftmodule</key>
<dict>
<key>hash2</key>
<data>
3c9ySZmIlwDKytG5fZJdG7935xyazWWJyynK8quXFog=
</data>
</dict>
<key>Modules/module.modulemap</key>
<dict>
<key>hash2</key>
<data>
YDtFEEzLR2yg17dFh3mHh8+toQhjIji37E2uywRgszw=
</data>
</dict>
<key>README.md</key>
<dict>
<key>hash2</key>
<data>
n16dJqv8U7weSFHiGdo4QvM6hRx5lBWEUTIGNq9c7FM=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,696 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
DC2A648F26A86CE0004D1AA6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2A648E26A86CE0004D1AA6 /* AppDelegate.swift */; };
DC2A649126A86CE0004D1AA6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2A649026A86CE0004D1AA6 /* SceneDelegate.swift */; };
DC2A649326A86CE0004D1AA6 /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2A649226A86CE0004D1AA6 /* HomeViewController.swift */; };
DC2A649626A86CE0004D1AA6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC2A649426A86CE0004D1AA6 /* Main.storyboard */; };
DC2A649826A86CE3004D1AA6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC2A649726A86CE3004D1AA6 /* Assets.xcassets */; };
DC2A649B26A86CE3004D1AA6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC2A649926A86CE3004D1AA6 /* LaunchScreen.storyboard */; };
DC62AFD62756941B00AC3E9C /* Blurit_SDK.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC62AFD42756939200AC3E9C /* Blurit_SDK.xcframework */; };
DC62AFD72756941B00AC3E9C /* Blurit_SDK.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DC62AFD42756939200AC3E9C /* Blurit_SDK.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
DC8945142719C65C003B88B1 /* ImageBlurredDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC8945132719C65C003B88B1 /* ImageBlurredDetailsViewController.swift */; };
DC8945172719CB08003B88B1 /* ProcessedMediaCVCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC8945162719CB08003B88B1 /* ProcessedMediaCVCell.swift */; };
DCB8673B2726EF1B0093EA34 /* UIViewControllerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB8673A2726EF1B0093EA34 /* UIViewControllerExtension.swift */; };
DCE89EB5271D741E00243E8A /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DCE89EB4271D741E00243E8A /* Colors.xcassets */; };
DCEC290826C186BD0023203F /* BluritService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCEC290726C186BD0023203F /* BluritService.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
DC8742882746A06F007F9932 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DC87426D2746A06F007F9932 /* FacelyticsSDKSampleProject.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = DCEDA3E4238FE45B00102D14;
remoteInfo = FacelyticsSDKSampleProject;
};
DC87428A2746A06F007F9932 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DC87426D2746A06F007F9932 /* FacelyticsSDKSampleProject.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = DCEDA3FA238FE45E00102D14;
remoteInfo = FacelyticsSDKSampleProjectTests;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
DC2A64B226A86EB7004D1AA6 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
DC62AFD72756941B00AC3E9C /* Blurit_SDK.xcframework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
DC2A648B26A86CE0004D1AA6 /* BluritSampleProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BluritSampleProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
DC2A648E26A86CE0004D1AA6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DC2A649026A86CE0004D1AA6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
DC2A649226A86CE0004D1AA6 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = "<group>"; };
DC2A649526A86CE0004D1AA6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
DC2A649726A86CE3004D1AA6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
DC2A649A26A86CE3004D1AA6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
DC2A649C26A86CE3004D1AA6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DC62AFD42756939200AC3E9C /* Blurit_SDK.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Blurit_SDK.xcframework; path = ../Blurit_SDK.xcframework; sourceTree = "<group>"; };
DC8742582746A06F007F9932 /* BluritSampleProject.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = BluritSampleProject.xcodeproj; sourceTree = "<group>"; };
DC87425C2746A06F007F9932 /* Facelytics_SDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Facelytics_SDK.framework; sourceTree = "<group>"; };
DC87425D2746A06F007F9932 /* ZIPFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ZIPFoundation.framework; sourceTree = "<group>"; };
DC87425E2746A06F007F9932 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
DC8742602746A06F007F9932 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
DC8742622746A06F007F9932 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
DC8742642746A06F007F9932 /* PredictionResultCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PredictionResultCollectionViewController.swift; sourceTree = "<group>"; };
DC8742652746A06F007F9932 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = "<group>"; };
DC8742662746A06F007F9932 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DC8742682746A06F007F9932 /* PredictionResultCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PredictionResultCollectionViewCell.swift; sourceTree = "<group>"; };
DC8742692746A06F007F9932 /* GroupToPredictCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupToPredictCollectionViewCell.swift; sourceTree = "<group>"; };
DC87426A2746A06F007F9932 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DC87426C2746A06F007F9932 /* FacelyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacelyticsService.swift; sourceTree = "<group>"; };
DC87426D2746A06F007F9932 /* FacelyticsSDKSampleProject.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = FacelyticsSDKSampleProject.xcodeproj; sourceTree = "<group>"; };
DC8742732746A06F007F9932 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
DC8742752746A06F007F9932 /* UIViewControllerExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtension.swift; sourceTree = "<group>"; };
DC8742772746A06F007F9932 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
DC8742782746A06F007F9932 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
DC87427A2746A06F007F9932 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
DC87427C2746A06F007F9932 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = "<group>"; };
DC87427D2746A06F007F9932 /* ImageBlurredDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageBlurredDetailsViewController.swift; sourceTree = "<group>"; };
DC87427F2746A06F007F9932 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DC8742812746A06F007F9932 /* ProcessedMediaCVCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessedMediaCVCell.swift; sourceTree = "<group>"; };
DC8742822746A06F007F9932 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DC8742842746A06F007F9932 /* BluritService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluritService.swift; sourceTree = "<group>"; };
DC8742852746A06F007F9932 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
DC8945132719C65C003B88B1 /* ImageBlurredDetailsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageBlurredDetailsViewController.swift; sourceTree = "<group>"; };
DC8945162719CB08003B88B1 /* ProcessedMediaCVCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessedMediaCVCell.swift; sourceTree = "<group>"; };
DCB8673A2726EF1B0093EA34 /* UIViewControllerExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtension.swift; sourceTree = "<group>"; };
DCE89EB4271D741E00243E8A /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
DCEC290726C186BD0023203F /* BluritService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluritService.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
DC2A648826A86CE0004D1AA6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DC62AFD62756941B00AC3E9C /* Blurit_SDK.xcframework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
DC2A648226A86CE0004D1AA6 = {
isa = PBXGroup;
children = (
DC2A648D26A86CE0004D1AA6 /* BluritSampleProject */,
DC2A648C26A86CE0004D1AA6 /* Products */,
DC2A64AE26A86EB6004D1AA6 /* Frameworks */,
);
sourceTree = "<group>";
};
DC2A648C26A86CE0004D1AA6 /* Products */ = {
isa = PBXGroup;
children = (
DC2A648B26A86CE0004D1AA6 /* BluritSampleProject.app */,
);
name = Products;
sourceTree = "<group>";
};
DC2A648D26A86CE0004D1AA6 /* BluritSampleProject */ = {
isa = PBXGroup;
children = (
DC2A648E26A86CE0004D1AA6 /* AppDelegate.swift */,
DC89451027188A7E003B88B1 /* Model */,
DCEC290626C186A90023203F /* Services */,
DC2A649026A86CE0004D1AA6 /* SceneDelegate.swift */,
DC883C4426C4234100ED2086 /* ViewControllers */,
DC8945152719CAD4003B88B1 /* Views */,
DC883C4226C41E5A00ED2086 /* Storyboards */,
DCB867392726EEFD0093EA34 /* Extension */,
DC883C4326C4219B00ED2086 /* Resources */,
DC2A649926A86CE3004D1AA6 /* LaunchScreen.storyboard */,
DC2A649C26A86CE3004D1AA6 /* Info.plist */,
);
path = BluritSampleProject;
sourceTree = "<group>";
};
DC2A64AE26A86EB6004D1AA6 /* Frameworks */ = {
isa = PBXGroup;
children = (
DC62AFD42756939200AC3E9C /* Blurit_SDK.xcframework */,
DC8742572746A06F007F9932 /* Example */,
);
name = Frameworks;
sourceTree = "<group>";
};
DC8742572746A06F007F9932 /* Example */ = {
isa = PBXGroup;
children = (
DC8742582746A06F007F9932 /* BluritSampleProject.xcodeproj */,
DC87425B2746A06F007F9932 /* FacelyticsSDKSampleProject */,
DC87426D2746A06F007F9932 /* FacelyticsSDKSampleProject.xcodeproj */,
DC8742702746A06F007F9932 /* BluritSampleProject */,
);
name = Example;
sourceTree = "<group>";
};
DC8742592746A06F007F9932 /* Products */ = {
isa = PBXGroup;
name = Products;
sourceTree = "<group>";
};
DC87425B2746A06F007F9932 /* FacelyticsSDKSampleProject */ = {
isa = PBXGroup;
children = (
DC87425C2746A06F007F9932 /* Facelytics_SDK.framework */,
DC87425D2746A06F007F9932 /* ZIPFoundation.framework */,
DC87425E2746A06F007F9932 /* Assets.xcassets */,
DC87425F2746A06F007F9932 /* LaunchScreen.storyboard */,
DC8742612746A06F007F9932 /* Main.storyboard */,
DC8742632746A06F007F9932 /* ViewControllers */,
DC8742662746A06F007F9932 /* AppDelegate.swift */,
DC8742672746A06F007F9932 /* Views */,
DC87426A2746A06F007F9932 /* Info.plist */,
DC87426B2746A06F007F9932 /* Services */,
);
path = FacelyticsSDKSampleProject;
sourceTree = "<group>";
};
DC8742632746A06F007F9932 /* ViewControllers */ = {
isa = PBXGroup;
children = (
DC8742642746A06F007F9932 /* PredictionResultCollectionViewController.swift */,
DC8742652746A06F007F9932 /* HomeViewController.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
};
DC8742672746A06F007F9932 /* Views */ = {
isa = PBXGroup;
children = (
DC8742682746A06F007F9932 /* PredictionResultCollectionViewCell.swift */,
DC8742692746A06F007F9932 /* GroupToPredictCollectionViewCell.swift */,
);
path = Views;
sourceTree = "<group>";
};
DC87426B2746A06F007F9932 /* Services */ = {
isa = PBXGroup;
children = (
DC87426C2746A06F007F9932 /* FacelyticsService.swift */,
);
path = Services;
sourceTree = "<group>";
};
DC87426E2746A06F007F9932 /* Products */ = {
isa = PBXGroup;
children = (
DC8742892746A06F007F9932 /* FacelyticsSample.app */,
DC87428B2746A06F007F9932 /* FacelyticsSDKSampleProjectTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
DC8742702746A06F007F9932 /* BluritSampleProject */ = {
isa = PBXGroup;
children = (
DC8742712746A06F007F9932 /* Storyboards */,
DC8742742746A06F007F9932 /* Extension */,
DC8742762746A06F007F9932 /* Resources */,
DC8742792746A06F007F9932 /* LaunchScreen.storyboard */,
DC87427B2746A06F007F9932 /* ViewControllers */,
DC87427E2746A06F007F9932 /* Model */,
DC87427F2746A06F007F9932 /* AppDelegate.swift */,
DC8742802746A06F007F9932 /* Views */,
DC8742822746A06F007F9932 /* Info.plist */,
DC8742832746A06F007F9932 /* Services */,
DC8742852746A06F007F9932 /* SceneDelegate.swift */,
);
path = BluritSampleProject;
sourceTree = "<group>";
};
DC8742712746A06F007F9932 /* Storyboards */ = {
isa = PBXGroup;
children = (
DC8742722746A06F007F9932 /* Main.storyboard */,
);
path = Storyboards;
sourceTree = "<group>";
};
DC8742742746A06F007F9932 /* Extension */ = {
isa = PBXGroup;
children = (
DC8742752746A06F007F9932 /* UIViewControllerExtension.swift */,
);
path = Extension;
sourceTree = "<group>";
};
DC8742762746A06F007F9932 /* Resources */ = {
isa = PBXGroup;
children = (
DC8742772746A06F007F9932 /* Colors.xcassets */,
DC8742782746A06F007F9932 /* Assets.xcassets */,
);
path = Resources;
sourceTree = "<group>";
};
DC87427B2746A06F007F9932 /* ViewControllers */ = {
isa = PBXGroup;
children = (
DC87427C2746A06F007F9932 /* HomeViewController.swift */,
DC87427D2746A06F007F9932 /* ImageBlurredDetailsViewController.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
};
DC87427E2746A06F007F9932 /* Model */ = {
isa = PBXGroup;
children = (
);
path = Model;
sourceTree = "<group>";
};
DC8742802746A06F007F9932 /* Views */ = {
isa = PBXGroup;
children = (
DC8742812746A06F007F9932 /* ProcessedMediaCVCell.swift */,
);
path = Views;
sourceTree = "<group>";
};
DC8742832746A06F007F9932 /* Services */ = {
isa = PBXGroup;
children = (
DC8742842746A06F007F9932 /* BluritService.swift */,
);
path = Services;
sourceTree = "<group>";
};
DC883C4226C41E5A00ED2086 /* Storyboards */ = {
isa = PBXGroup;
children = (
DC2A649426A86CE0004D1AA6 /* Main.storyboard */,
);
path = Storyboards;
sourceTree = "<group>";
};
DC883C4326C4219B00ED2086 /* Resources */ = {
isa = PBXGroup;
children = (
DC2A649726A86CE3004D1AA6 /* Assets.xcassets */,
DCE89EB4271D741E00243E8A /* Colors.xcassets */,
);
path = Resources;
sourceTree = "<group>";
};
DC883C4426C4234100ED2086 /* ViewControllers */ = {
isa = PBXGroup;
children = (
DC8945132719C65C003B88B1 /* ImageBlurredDetailsViewController.swift */,
DC2A649226A86CE0004D1AA6 /* HomeViewController.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
};
DC89451027188A7E003B88B1 /* Model */ = {
isa = PBXGroup;
children = (
);
path = Model;
sourceTree = "<group>";
};
DC8945152719CAD4003B88B1 /* Views */ = {
isa = PBXGroup;
children = (
DC8945162719CB08003B88B1 /* ProcessedMediaCVCell.swift */,
);
path = Views;
sourceTree = "<group>";
};
DCB867392726EEFD0093EA34 /* Extension */ = {
isa = PBXGroup;
children = (
DCB8673A2726EF1B0093EA34 /* UIViewControllerExtension.swift */,
);
path = Extension;
sourceTree = "<group>";
};
DCEC290626C186A90023203F /* Services */ = {
isa = PBXGroup;
children = (
DCEC290726C186BD0023203F /* BluritService.swift */,
);
path = Services;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
DC2A648A26A86CE0004D1AA6 /* BluritSampleProject */ = {
isa = PBXNativeTarget;
buildConfigurationList = DC2A649F26A86CE3004D1AA6 /* Build configuration list for PBXNativeTarget "BluritSampleProject" */;
buildPhases = (
DC2A648726A86CE0004D1AA6 /* Sources */,
DC2A648826A86CE0004D1AA6 /* Frameworks */,
DC2A648926A86CE0004D1AA6 /* Resources */,
DC2A64B226A86EB7004D1AA6 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = BluritSampleProject;
productName = BluritSampleProject;
productReference = DC2A648B26A86CE0004D1AA6 /* BluritSampleProject.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
DC2A648326A86CE0004D1AA6 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1250;
LastUpgradeCheck = 1250;
TargetAttributes = {
DC2A648A26A86CE0004D1AA6 = {
CreatedOnToolsVersion = 12.5;
};
};
};
buildConfigurationList = DC2A648626A86CE0004D1AA6 /* Build configuration list for PBXProject "BluritSampleProject" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = DC2A648226A86CE0004D1AA6;
productRefGroup = DC2A648C26A86CE0004D1AA6 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = DC8742592746A06F007F9932 /* Products */;
ProjectRef = DC8742582746A06F007F9932 /* BluritSampleProject.xcodeproj */;
},
{
ProductGroup = DC87426E2746A06F007F9932 /* Products */;
ProjectRef = DC87426D2746A06F007F9932 /* FacelyticsSDKSampleProject.xcodeproj */;
},
);
projectRoot = "";
targets = (
DC2A648A26A86CE0004D1AA6 /* BluritSampleProject */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
DC8742892746A06F007F9932 /* FacelyticsSample.app */ = {
isa = PBXReferenceProxy;
fileType = wrapper.application;
path = FacelyticsSample.app;
remoteRef = DC8742882746A06F007F9932 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
DC87428B2746A06F007F9932 /* FacelyticsSDKSampleProjectTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = FacelyticsSDKSampleProjectTests.xctest;
remoteRef = DC87428A2746A06F007F9932 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
DC2A648926A86CE0004D1AA6 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DC2A649B26A86CE3004D1AA6 /* LaunchScreen.storyboard in Resources */,
DCE89EB5271D741E00243E8A /* Colors.xcassets in Resources */,
DC2A649826A86CE3004D1AA6 /* Assets.xcassets in Resources */,
DC2A649626A86CE0004D1AA6 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
DC2A648726A86CE0004D1AA6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DC8945142719C65C003B88B1 /* ImageBlurredDetailsViewController.swift in Sources */,
DC2A649326A86CE0004D1AA6 /* HomeViewController.swift in Sources */,
DCEC290826C186BD0023203F /* BluritService.swift in Sources */,
DC2A648F26A86CE0004D1AA6 /* AppDelegate.swift in Sources */,
DC2A649126A86CE0004D1AA6 /* SceneDelegate.swift in Sources */,
DCB8673B2726EF1B0093EA34 /* UIViewControllerExtension.swift in Sources */,
DC8945172719CB08003B88B1 /* ProcessedMediaCVCell.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
DC2A649426A86CE0004D1AA6 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
DC2A649526A86CE0004D1AA6 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
DC2A649926A86CE3004D1AA6 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
DC2A649A26A86CE3004D1AA6 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
DC87425F2746A06F007F9932 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
DC8742602746A06F007F9932 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
DC8742612746A06F007F9932 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
DC8742622746A06F007F9932 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
DC8742722746A06F007F9932 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
DC8742732746A06F007F9932 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
DC8742792746A06F007F9932 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
DC87427A2746A06F007F9932 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
DC2A649D26A86CE3004D1AA6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
DC2A649E26A86CE3004D1AA6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
DC2A64A026A86CE3004D1AA6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 64Z6476XJF;
INFOPLIST_FILE = BluritSampleProject/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = io.wassa.BluritSampleProject;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
DC2A64A126A86CE3004D1AA6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 64Z6476XJF;
INFOPLIST_FILE = BluritSampleProject/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = io.wassa.BluritSampleProject;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
DC2A648626A86CE0004D1AA6 /* Build configuration list for PBXProject "BluritSampleProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DC2A649D26A86CE3004D1AA6 /* Debug */,
DC2A649E26A86CE3004D1AA6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DC2A649F26A86CE3004D1AA6 /* Build configuration list for PBXNativeTarget "BluritSampleProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DC2A64A026A86CE3004D1AA6 /* Debug */,
DC2A64A126A86CE3004D1AA6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = DC2A648326A86CE0004D1AA6 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DC2A648A26A86CE0004D1AA6"
BuildableName = "BluritSampleProject.app"
BlueprintName = "BluritSampleProject"
ReferencedContainer = "container:BluritSampleProject.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DC2A648A26A86CE0004D1AA6"
BuildableName = "BluritSampleProject.app"
BlueprintName = "BluritSampleProject"
ReferencedContainer = "container:BluritSampleProject.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DC2A648A26A86CE0004D1AA6"
BuildableName = "BluritSampleProject.app"
BlueprintName = "BluritSampleProject"
ReferencedContainer = "container:BluritSampleProject.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,39 @@
//
// AppDelegate.swift
// BluritSampleProject
//
// Created by Bertrand VILLAIN on 21/07/2021.
//
import UIKit
import AVFoundation
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.playback, mode: .moviePlayback)
} catch {
print("Setting category to AVAudioSessionCategoryPlayback failed.")
}
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,20 @@
//
// UIViewControllerExtension.swift
// BluritSampleProject
//
// Created by Bertrand VILLAIN on 25/10/2021.
//
import UIKit
extension UIViewController {
func alert(_ title: String?, _ message: String?, _ completion: (() -> Void)? = nil) {
let alertVC = UIAlertController(title: title, message: message, preferredStyle: .alert)
alertVC.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
completion?()
}))
self.present(alertVC, animated: true, completion: nil)
}
}

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Test</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_1.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_10.jpeg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_11.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_12.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_13.jpeg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "family.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "Dialogue_Camp_call_2021.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "DSC_2176_DxO.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "test.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_18.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_2.jpeg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_3.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_4.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_5.jpeg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "group_6.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "film-roll.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,56 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.986",
"alpha" : "1.000",
"blue" : "0.950",
"green" : "0.986"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.986",
"alpha" : "1.000",
"blue" : "0.950",
"green" : "1.000"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.343",
"alpha" : "1.000",
"blue" : "0.343",
"green" : "0.343"
}
}
}
]
}

View File

@ -0,0 +1,56 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.990",
"alpha" : "1.000",
"blue" : "0.990",
"green" : "0.990"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.990",
"alpha" : "1.000",
"blue" : "0.990",
"green" : "0.990"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.375",
"alpha" : "1.000",
"blue" : "0.375",
"green" : "0.375"
}
}
}
]
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,52 @@
//
// SceneDelegate.swift
// BluritSampleProject
//
// Created by Bertrand VILLAIN on 21/07/2021.
//
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}

View File

@ -0,0 +1,37 @@
//
// BluritService.swift
// BluritSampleProject
//
// Created by Bertrand VILLAIN on 09/08/2021.
//
import Blurit_SDK
class BluritService {
let licenseKey = ""
static let shared = BluritService() // 2. Shared instance
private init() {}
var bluritInstance: Blurit?
var serviceStarted = false
/**
The service must be initialized at the app starting
*/
func initService() {
bluritInstance = Blurit(licenceKey: licenseKey, completion: nil)
DispatchQueue.global().async {
self.bluritInstance?.loadModels(completion: { (error) in
if let error = error {
print("❌ Cannot initialize Blurit \(error.localizedDescription)")
} else {
print("Facelytics model successfully loaded ✅")
self.serviceStarted = true
}
})
}
}
}

View File

@ -0,0 +1,225 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="XyQ-Cd-2mE">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="collection view cell content view" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Home View Controller-->
<scene sceneID="5Wx-3j-f2b">
<objects>
<viewController id="XyQ-Cd-2mE" customClass="HomeViewController" customModule="BluritSampleProject" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Bpy-UW-hCF">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dBu-7P-kPQ">
<rect key="frame" x="12" y="50" width="390" height="160"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kq9-wb-k11">
<rect key="frame" x="78" y="24" width="234" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="SFz-tc-jUH"/>
</constraints>
<color key="tintColor" red="0.28918531886535631" green="0.44688859363957223" blue="0.66304139416627206" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Process a picture"/>
<connections>
<action selector="choosePictureTouched:" destination="XyQ-Cd-2mE" eventType="touchUpInside" id="YSV-aL-XlD"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4eX-J9-W9I">
<rect key="frame" x="78" y="96" width="234" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="eu8-K7-Q4i"/>
</constraints>
<color key="tintColor" red="0.008882958977984785" green="0.79215412003559027" blue="0.0" alpha="0.90005917580711925" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Process a video">
<color key="baseBackgroundColor" red="0.0088829589780000003" green="0.79215411999999996" blue="0.0" alpha="0.90005917580000006" colorSpace="custom" customColorSpace="sRGB"/>
</buttonConfiguration>
<connections>
<action selector="chooseVideoTouched:" destination="XyQ-Cd-2mE" eventType="touchUpInside" id="Oe3-p9-LP5"/>
</connections>
</button>
<progressView hidden="YES" opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="dBP-na-Z0x">
<rect key="frame" x="78" y="78" width="234" height="4"/>
</progressView>
</subviews>
<color key="backgroundColor" red="0.91140368862140253" green="0.91074560978439745" blue="0.92039589930062349" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="4eX-J9-W9I" firstAttribute="width" secondItem="kq9-wb-k11" secondAttribute="width" id="6dl-on-maq"/>
<constraint firstItem="kq9-wb-k11" firstAttribute="width" secondItem="dBu-7P-kPQ" secondAttribute="width" multiplier="0.6" id="B9Y-oJ-HtF"/>
<constraint firstItem="kq9-wb-k11" firstAttribute="top" secondItem="dBu-7P-kPQ" secondAttribute="top" constant="24" id="E62-Mk-bLb"/>
<constraint firstAttribute="height" constant="160" id="G2u-RR-kVC"/>
<constraint firstItem="4eX-J9-W9I" firstAttribute="centerX" secondItem="dBu-7P-kPQ" secondAttribute="centerX" id="NoS-lf-f1T"/>
<constraint firstItem="kq9-wb-k11" firstAttribute="centerX" secondItem="dBu-7P-kPQ" secondAttribute="centerX" id="hyr-w2-8lM"/>
<constraint firstItem="dBP-na-Z0x" firstAttribute="centerY" secondItem="dBu-7P-kPQ" secondAttribute="centerY" id="j80-Ta-Fay"/>
<constraint firstAttribute="bottom" secondItem="4eX-J9-W9I" secondAttribute="bottom" constant="24" id="jOi-Bq-V9L"/>
<constraint firstItem="dBP-na-Z0x" firstAttribute="leading" secondItem="kq9-wb-k11" secondAttribute="leading" id="mwt-Ha-PJ5"/>
<constraint firstItem="dBP-na-Z0x" firstAttribute="trailing" secondItem="kq9-wb-k11" secondAttribute="trailing" id="rYF-pT-ZzT"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="12"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="gRX-bT-Qoz">
<rect key="frame" x="0.0" y="222" width="414" height="674"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="12" minimumInteritemSpacing="10" id="vUX-mY-sk8">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="10" minY="8" maxX="10" maxY="8"/>
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="ProcessedMediaCVCell" id="Tid-bK-fUm" customClass="ProcessedMediaCVCell" customModule="BluritSampleProject" customModuleProvider="target">
<rect key="frame" x="10" y="8" width="130" height="130"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<collectionViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="UQi-Gg-yrn">
<rect key="frame" x="0.0" y="0.0" width="130" height="130"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="hz2-hM-Sec">
<rect key="frame" x="0.0" y="0.0" width="130" height="130"/>
<constraints>
<constraint firstAttribute="width" secondItem="hz2-hM-Sec" secondAttribute="height" multiplier="1:1" id="GZu-h8-pV4"/>
<constraint firstAttribute="height" priority="998" constant="130" id="u6H-R0-btm"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrowtriangle.forward.fill" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="Ayb-w3-i9N">
<rect key="frame" x="45" y="55" width="40" height="35.5"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="Aa7-H1-HYO"/>
<constraint firstAttribute="width" constant="40" id="MkQ-wi-lOD"/>
</constraints>
</imageView>
</subviews>
<constraints>
<constraint firstItem="Ayb-w3-i9N" firstAttribute="centerX" secondItem="UQi-Gg-yrn" secondAttribute="centerX" id="1qY-Db-466"/>
<constraint firstItem="hz2-hM-Sec" firstAttribute="leading" secondItem="UQi-Gg-yrn" secondAttribute="leading" id="6fV-Ol-dF0"/>
<constraint firstAttribute="bottom" secondItem="hz2-hM-Sec" secondAttribute="bottom" id="FOH-cb-Wjt"/>
<constraint firstItem="Ayb-w3-i9N" firstAttribute="centerY" secondItem="UQi-Gg-yrn" secondAttribute="centerY" constant="8" id="Sfi-aY-xNu"/>
<constraint firstAttribute="trailing" secondItem="hz2-hM-Sec" secondAttribute="trailing" id="lCQ-Xw-TCQ"/>
<constraint firstItem="hz2-hM-Sec" firstAttribute="top" secondItem="UQi-Gg-yrn" secondAttribute="top" id="v3M-aC-tU6"/>
</constraints>
</collectionViewCellContentView>
<size key="customSize" width="130" height="130"/>
<connections>
<outlet property="heightImageConstraint" destination="u6H-R0-btm" id="NpP-Lh-Yar"/>
<outlet property="imageView" destination="hz2-hM-Sec" id="K2e-yn-HkZ"/>
<outlet property="playImageView" destination="Ayb-w3-i9N" id="tlU-yo-1Vz"/>
</connections>
</collectionViewCell>
</cells>
<connections>
<outlet property="dataSource" destination="XyQ-Cd-2mE" id="fxx-eL-p1b"/>
<outlet property="delegate" destination="XyQ-Cd-2mE" id="Jxh-e0-4Bz"/>
</connections>
</collectionView>
</subviews>
<viewLayoutGuide key="safeArea" id="iOq-L0-Ykl"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="gRX-bT-Qoz" secondAttribute="bottom" id="70S-GI-BOK"/>
<constraint firstItem="iOq-L0-Ykl" firstAttribute="trailing" secondItem="gRX-bT-Qoz" secondAttribute="trailing" id="GaD-2h-lHG"/>
<constraint firstItem="dBu-7P-kPQ" firstAttribute="leading" secondItem="iOq-L0-Ykl" secondAttribute="leading" constant="12" id="LLj-ip-dcW"/>
<constraint firstItem="dBu-7P-kPQ" firstAttribute="top" secondItem="iOq-L0-Ykl" secondAttribute="top" constant="6" id="eTP-j4-iUh"/>
<constraint firstItem="gRX-bT-Qoz" firstAttribute="top" secondItem="dBu-7P-kPQ" secondAttribute="bottom" constant="12" id="hMb-hI-KTv"/>
<constraint firstItem="iOq-L0-Ykl" firstAttribute="trailing" secondItem="dBu-7P-kPQ" secondAttribute="trailing" constant="12" id="x1P-3O-eHl"/>
<constraint firstItem="gRX-bT-Qoz" firstAttribute="leading" secondItem="iOq-L0-Ykl" secondAttribute="leading" id="y9U-yw-Te9"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="QPo-rq-lss"/>
<nil key="simulatedTopBarMetrics"/>
<connections>
<outlet property="collectionView" destination="gRX-bT-Qoz" id="xMw-fe-vNT"/>
<outlet property="progressView" destination="dBP-na-Z0x" id="6jh-gf-eMB"/>
<segue destination="iYJ-L0-dOw" kind="showDetail" identifier="ImageBlurredDetailsViewController" id="dJl-jx-7vQ"/>
<segue destination="3mx-Bk-asX" kind="show" id="hqK-03-SyQ"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="4r0-aN-8ml" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="332" y="202"/>
</scene>
<!--Image Blurred Details View Controller-->
<scene sceneID="KN7-WR-5iE">
<objects>
<viewController storyboardIdentifier="ImageBlurredDetailsViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="iYJ-L0-dOw" customClass="ImageBlurredDetailsViewController" customModule="BluritSampleProject" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="fBg-I0-lDE">
<rect key="frame" x="0.0" y="0.0" width="414" height="842"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="opi-zt-xWD">
<rect key="frame" x="0.0" y="0.0" width="414" height="300"/>
<constraints>
<constraint firstAttribute="height" priority="999" constant="300" id="JHN-ff-F9A"/>
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="400" id="YPp-q0-hsF"/>
</constraints>
</imageView>
<button opaque="NO" contentMode="scaleAspectFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ctR-5L-106" userLabel="close">
<rect key="frame" x="360" y="14" width="40" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="40" id="SWR-bC-4gz"/>
<constraint firstAttribute="height" constant="40" id="V3z-Bf-J1U"/>
</constraints>
<color key="tintColor" red="0.97745031120000003" green="0.98015910390000005" blue="0.99700921769999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" image="icon_close"/>
<connections>
<action selector="touchUpInside:" destination="iYJ-L0-dOw" eventType="touchUpInside" id="TIk-Mx-F00"/>
</connections>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="tT4-Cf-wH6"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="opi-zt-xWD" firstAttribute="top" secondItem="tT4-Cf-wH6" secondAttribute="top" id="FGA-cR-lfy"/>
<constraint firstItem="tT4-Cf-wH6" firstAttribute="trailing" secondItem="opi-zt-xWD" secondAttribute="trailing" id="Kbe-QE-13h"/>
<constraint firstItem="ctR-5L-106" firstAttribute="top" secondItem="tT4-Cf-wH6" secondAttribute="top" constant="14" id="aRO-q7-cDo"/>
<constraint firstItem="opi-zt-xWD" firstAttribute="leading" secondItem="tT4-Cf-wH6" secondAttribute="leading" id="adk-9p-IRQ"/>
<constraint firstItem="tT4-Cf-wH6" firstAttribute="trailing" secondItem="ctR-5L-106" secondAttribute="trailing" constant="14" id="pd1-Qi-C1V"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="jia-JP-N3J"/>
<connections>
<outlet property="detailImageView" destination="opi-zt-xWD" id="p7z-bl-uay"/>
<outlet property="sourceImageHeightConstraint" destination="JHN-ff-F9A" id="isQ-sN-eEq"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="NNf-jz-25T" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1296" y="-61"/>
</scene>
<!--AV Player View Controller-->
<scene sceneID="Hw1-s3-DEt">
<objects>
<avPlayerViewController videoGravity="AVLayerVideoGravityResizeAspect" id="3mx-Bk-asX" sceneMemberID="viewController">
<navigationItem key="navigationItem" id="SPK-xc-IM2"/>
</avPlayerViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="7c6-HM-LtJ" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1296" y="610"/>
</scene>
</scenes>
<resources>
<image name="arrowtriangle.forward.fill" catalog="system" width="128" height="113"/>
<image name="icon_close" width="128" height="128"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@ -0,0 +1,172 @@
//
// HomeViewController.swift
// BluritSampleProject
//
// Created by Bertrand VILLAIN on 21/07/2021.
//
import UIKit
import AVFoundation
import AVKit
/**
That View Controller just list pictures or videos processed with Blurit.
You can also edit the dataSource returned in the collectionView
*/
class HomeViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var progressView: UIProgressView!
var gradientLayer: CAGradientLayer!
var processedMediaDataSource: [ProcessedMediaDataSource] = []
var imagePickerController = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
BluritService.shared.initService()
imagePickerController.delegate = self
self.collectionView.reloadData()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if let nextVC = segue.destination as? ImageBlurredDetailsViewController {
nextVC.dataSource = sender as? ProcessedMediaDataSource
}
}
func applyGradientForBackground() {
guard let firstColor = UIColor(named: "PrimaryBackgroundColor"),
let secondColor = UIColor(named: "SecondaryBackgroundColor") else { return }
gradientLayer = CAGradientLayer()
gradientLayer.frame = self.view.bounds
gradientLayer.colors = [firstColor.cgColor, secondColor.cgColor]
self.view.layer.insertSublayer(gradientLayer, at: 0)
}
func handlePickedImage(image: UIImage) {
guard BluritService.shared.serviceStarted else {
self.alert(nil, "Service not yet started", nil)
return
}
BluritService.shared.bluritInstance?.detectObjectsAsync(sourceImage: image, completion: { firstCompletionResult in
switch firstCompletionResult {
case .success(let predictionResult):
BluritService.shared.bluritInstance?.anonymizeAsync(sourceImage: image, predictionResult: predictionResult, completion: { secondCompletionResult in
switch secondCompletionResult {
case .success(let processedImage):
let processedDataSource = ProcessedMediaDataSource(sourceImage: image, blurredImage: processedImage)
self.processedMediaDataSource.append(processedDataSource)
self.collectionView.reloadData()
case .failure(let error):
self.alert(nil, error.localizedDescription)
}
})
case .failure(let error):
self.alert(nil, error.localizedDescription)
}
})
}
func handlePickedVideo(videoUrl: URL) {
guard BluritService.shared.serviceStarted else {
self.alert(nil, "Service not yet started", nil)
return
}
BluritService.shared.bluritInstance?.detectObjectsAsync(videoUrl: videoUrl, completion: { firstCompletionResult in
switch firstCompletionResult {
case .success(let predictionResult):
BluritService.shared.bluritInstance?.anonymizeAsync(videoUrl: videoUrl, predictionResult: predictionResult, completion: { secondCompletionResult in
switch secondCompletionResult {
case .success(let processedVideoUrl):
let processedDataSource = ProcessedMediaDataSource(sourceVideoUrl: videoUrl, blurredVideoUrl: processedVideoUrl, previewImage: #imageLiteral(resourceName: "film_roll"))
self.processedMediaDataSource.append(processedDataSource)
self.collectionView.reloadData()
case .failure(let error):
self.alert(nil, error.localizedDescription)
}
})
case .failure(let error):
self.alert(nil, error.localizedDescription)
}
})
}
//MARK: IBActions
@IBAction func choosePictureTouched(_ sender: Any) {
imagePickerController.sourceType = .savedPhotosAlbum
imagePickerController.mediaTypes = ["public.image"]
present(imagePickerController, animated: true, completion: nil)
}
@IBAction func chooseVideoTouched(_ sender: Any) {
imagePickerController.sourceType = .savedPhotosAlbum
imagePickerController.mediaTypes = ["public.movie"]
present(imagePickerController, animated: true, completion: nil)
}
}
extension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return processedMediaDataSource.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let screenBounds = UIScreen.main.bounds
return CGSize(width: (screenBounds.width / 2) - 24, height: (screenBounds.width / 2) - 24)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "ProcessedMediaCVCell", for: indexPath) as! ProcessedMediaCVCell
cell.loadData(dataSource: processedMediaDataSource[indexPath.item])
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedMediaSource = processedMediaDataSource[indexPath.item]
if selectedMediaSource.type == .image {
self.performSegue(withIdentifier: "ImageBlurredDetailsViewController", sender: selectedMediaSource)
} else {
guard let videoUrl = selectedMediaSource.blurredVideoUrl else { return }
let player = AVPlayer(url: videoUrl)
// Create a new AVPlayerViewController and pass it a reference to the player.
let controller = AVPlayerViewController()
controller.player = player
// Modally present the player and call the player's play() method when complete.
present(controller, animated: true) {
player.play()
}
}
}
}
extension HomeViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
self.dismiss(animated: true, completion: nil)
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
self.handlePickedImage(image: image)
} else if let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL {
self.handlePickedVideo(videoUrl: videoURL)
}
}
}

View File

@ -0,0 +1,34 @@
//
// VideoBlurredDetailsViewController.swift
// FacelyticsSDKSampleProject
//
// Created by Bertrand VILLAIN on 15/10/2021.
// Copyright © 2021 Wassa. All rights reserved.
//
import UIKit
import AVFoundation
class ImageBlurredDetailsViewController: UIViewController {
@IBOutlet weak var sourceImageHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var detailImageView: UIImageView!
var dataSource: ProcessedMediaDataSource!
override func viewDidLoad() {
super.viewDidLoad()
guard let sourceImage = dataSource.blurredImage else { return }
let sourceRatio = sourceImage.size.height / sourceImage.size.width
sourceImageHeightConstraint.constant = detailImageView.frame.width * sourceRatio
detailImageView.image = sourceImage
}
/**
Returns to HomeViewController
*/
@IBAction func touchUpInside(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
}

View File

@ -0,0 +1,59 @@
//
// ProcessedMediaCVCell.swift
// BluritSampleProject
//
// Created by Bertrand VILLAIN on 15/10/2021.
//
import UIKit
class ProcessedMediaCVCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var heightImageConstraint: NSLayoutConstraint!
@IBOutlet weak var playImageView: UIImageView!
func loadData(dataSource: ProcessedMediaDataSource) {
let screenBounds = UIScreen.main.bounds
heightImageConstraint.constant = (screenBounds.width / 2) - 14
imageView.image = dataSource.previewImage
self.playImageView.isHidden = (dataSource.type == .image)
}
}
class ProcessedMediaDataSource {
let reuseIdentifier = "ProcessedMediaCVCell"
var type: MediaType
var previewImage: UIImage?
var sourceImage: UIImage?
var blurredImage: UIImage?
var sourceVideoUrl: URL?
var blurredVideoUrl: URL?
internal init(sourceImage: UIImage, blurredImage: UIImage?) {
self.type = .image
self.sourceImage = sourceImage
self.blurredImage = blurredImage
self.previewImage = blurredImage ?? sourceImage
}
internal init(sourceVideoUrl: URL?, blurredVideoUrl: URL?, previewImage: UIImage) {
self.type = .video
self.sourceVideoUrl = sourceVideoUrl
self.blurredVideoUrl = blurredVideoUrl
self.previewImage = previewImage
}
}
enum MediaType {
case image
case video
}

53
LICENSE.md Normal file
View File

@ -0,0 +1,53 @@
Copyright (c) 2019 Wassa <contact@wassa.fr>
Wassa is willing to license the Software to you only upon the condition that you accept all the terms contained in this Agreement. By checking the box with links to this Agreement, clicking “accept” or by downloading, installing or using the Software, you are agreeing that you understand this Agreement and accept all of its terms. If you are accepting the terms of this Agreement on behalf of a Legal Entity, you represent and warrant that you have the authority to bind that Legal Entity to the terms of this Agreement, and, in such event, “you” and “your” will refer to that Legal Entity. If you do not accept all the terms of this Agreement, then Wassa is unwilling to license the Software to you, and you must destroy all copies of the Software in your possession or control.
1. Grant of License.
1 Use Rights. Conditioned upon your compliance with the terms and conditions of this Agreement and payment of all applicable fees, Wassa grants you a non-exclusive, non-transferable license to install and deploy the Software, by a single person to develop Licensee Content during the applicable license term. You may not sublicense the rights granted.
2 Trial Product Restrictions. If you are using a trial version of the Software, you may not publish or distribute any Licensee Content.
2. Restrictions.
1 Except as expressly specified in this Agreement, you may not: (a) copy (except in the course of loading or installing) or modify or create derivative works of the Software; (b) distribute, transfer, sublicense, lease, lend, rent or otherwise provide access to the Software to any third party; (c) make the functionality of the Software available to multiple users or third parties through any means, including but not limited to by uploading the Software to a network or file-sharing service or through any hosting, application services provider, service bureau, software-as-a-service (SaaS) or any other type of services; (d) use the Software to develop a competing product; or (e) do anything that could cause or result in the Software (including the runtime portion thereof) being subject to any open source license (or similar license) that requires as a condition of use, modification or distribution that the Software (including the runtime portion thereof) or other software combined or distributed with the Software be: (i) disclosed or distributed in source code form; (ii) licensed for the purpose of making derivative works; or (iii) redistributable at no charge. You acknowledge and agree that portions of the Software, including but not limited to the source code and the specific design and structure of individual modules or programs, are confidential and constitute or contain trade secrets of Wassa and its licensors. Accordingly, you agree not to disassemble, decompile or reverse engineer the Software, in whole or in part, or permit or authorize a third party to do so, except to the extent such activities are expressly permitted by law notwithstanding this prohibition.
3. Ownership.
The Software is licensed, not sold. Wassa retains ownership of the Software including all intellectual property rights therein. The Software is protected by copyright law and international treaties. Wassa reserves all rights in the Software not expressly granted to you in this Agreement. You will not delete or in any manner alter any Wassa or third-party copyright, trademark or other proprietary rights notices or markings appearing on or in the Software (including the runtime portion thereof).
4. Fees and Taxes.
You agree to pay all amounts due for the Software as set forth in the applicable Wassa online store cart, quote and/or invoice. All license purchases are subject to the purchases, billing information and other terms set forth in the Blurit Term of Use and the subscription terms set forth on the Blurit web site. Wassa may offer other services in conjunction with Software and such services shall be subject to the applicable terms of service and fees. All fees payable under this Agreement are net amounts and are payable in full, without deduction for taxes or duties of any kind. You will be responsible for, and will promptly pay, all taxes and duties of any kind (including but not limited to sales, use and withholding taxes) associated with this Agreement or your receipt or use of the Software, except for taxes based on Wassas net income. In the event that Wassa is required to collect any tax for which you are responsible, you will pay such tax directly to Wassa. If you pay any withholding taxes that are required to be paid under applicable law, you will promptly furnish Wassa with written documentation of all such tax payments, including receipts.
5. Consent to Data Collection, Privacy Policy Obligations and Verification.
1 You acknowledge and accept Blurit privacy policy. You agree that the Software (including the Blurit runtime in your Licensee Content) may send data to Wassa to: (a) check for Software updates; (b) provide aggregated usage statistics of your use of the Software and the use of your Licensee Content by end users; (c) provide analytics and advertising services; and (d) validate license keys in order to prevent unauthorized use. You acknowledge and agree that Wassa may deliver messages and contact you about the Software and other Wassa products and service offerings.
2 You agree to distribute Licensee Content with a privacy policy explaining the data you collect through the Licensee Content and how you collect, use, share, and protect it; and to include a disclosure that Wassa is your service provider and collects certain data from your Licensee Content, along with a link to Blurit privacy policy, which may be updated from time to time.
3 To ensure compliance with this Agreement, you agree that within thirty (30) days from the date of Wassa or its authorized representatives request, you shall provide all pertinent records and information requested in order to verify that your installation and use of any and all Software is in compliance with this Agreement along with a signed verification that all such information is complete and correct. Furthermore, if you are a Legal Entity, Wassa or its authorized representatives may upon reasonable prior notice access and inspect your facilities and computer systems to review and verify your compliance with this Agreement. Any such inspection shall be conducted during regular business hours at your facilities or electronically via remote access. In the event you have impermissibly used Blurit (or other products) or have not paid the applicable fees for all Software you have deployed or used, you agree to promptly pay for such Software and the reasonable inspection costs.
6. Support.
You may access the Blurit documentation the Blurit web site. You may also email support@face-lytics.com for assistance with license keys. Technical support may be offered by Wassa at its sole discretion as described on the Blurit website. You acknowledge and agree that Wassa has no obligation under this Agreement to provide patches, updates, new releases or new versions of the Software.
7. Term.
If you have licensed a trial version of the Software, the license granted under this Agreement will remain in effect for 100 detections, unless earlier terminated in accordance with this Agreement. For paid in full, perpetual licenses, the license granted under this Agreement will remain in effect unless earlier terminated in accordance with this Agreement. For subscription based licenses, the license granted under this Agreement is for the initial subscription period, and thereafter such license will automatically renew on a month to month basis unless you renew the subscription for a new subscription term or terminate and cancel the license as described on the Blurit web site at the time of license purchase. Wassa may cease offering perpetual licenses and/or updates and new versions for such perpetual licenses and may modify or terminate subscription or other Software license or service offerings at any time. The license granted under this Agreement will automatically terminate, with or without notice from Wassa, if you breach any term of this Agreement or fail to pay all fees due for the license. Upon termination, you must at Wassas option either promptly delete and destroy or return to Wassa all copies of the Software in your possession or control. Wassa may also disable the Software you have licensed upon expiration of a subscription term license or in the event you breach this Agreement.
8. No Warranty.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND. WASSA AND ITS LICENSORS DISCLAIM ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT, AND ANY WARRANTIES AND CONDITIONS ARISING OUT OF COURSE OF DEALING OR USAGE OF TRADE. NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED FROM WASSA OR ELSEWHERE WILL CREATE ANY WARRANTY OR CONDITION NOT EXPRESSLY STATED IN THIS AGREEMENT.
9. Indemnity.
To the maximum extent permitted by law, you agree to indemnify, defend and hold harmless Wassa and its affiliates against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses, including, without limitation, reasonable legal fees, arising out of or accruing from your Licensee Content or your violation of this Agreement.
10. Limitation of Liability.
WASSA AND ITS LICENSORS TOTAL LIABILITY TO YOU FROM ALL CAUSES OF ACTION AND UNDER ALL THEORIES OF LIABILITY WILL BE LIMITED TO THE GREATER OF THE AMOUNTS PAID BY YOU FOR THE SOFTWARE OR ONE HUNDRED U.S. DOLLARS (US$100). IN NO EVENT WILL WASSA OR ITS LICENSORS BE LIABLE TO YOU FOR ANY SPECIAL, INCIDENTAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES (INCLUDING LOSS OF DATA, BUSINESS, PROFITS OR ABILITY TO EXECUTE) OR FOR THE COST OF PROCURING SUBSTITUTE PRODUCTS ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT OR THE EXECUTION OR PERFORMANCE OF THE SOFTWARE, WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, AND WHETHER OR NOT WASSA OR ITS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. THE FOREGOING LIMITATIONS WILL SURVIVE AND APPLY EVEN IF ANY LIMITED REMEDY SPECIFIED IN THIS AGREEMENT IS FOUND TO HAVE FAILED OF ITS ESSENTIAL PURPOSE. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE LIMITATION OR EXCLUSION MAY NOT APPLY TO YOU.
11. U.S. Government Rights.
The Software and computer software documentation (“Documentation”) are “commercial items” as that term is defined in the Federal Acquisition Regulation (“FAR”) 2.101, consisting of “commercial computer software” and “commercial computer software documentation,” respectively, as such terms are used in FAR 12.212 and DFARS 227.7202.If acquired by or on behalf of a civilian agency, the U.S. Government acquires or will acquire the Software and/or Documentation and other technical data subject to the terms of this Agreement as required in 48 C.F.R. 12.212 (Computer Software) and 12.211 (Technical Data) of the FAR and its successors. If acquired by or on behalf of any agency within the Department of Defense (“DOD”), the U.S. Government acquires or will acquire the Software and/or Documentation subject to the terms of this Agreement as specified in 48 C.F.R. 227.7202-3 of the DOD FAR Supplement (“DFARS”) and its successors. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFARS, or other clause or provision that addresses Government rights in computer software or technical data.
12. Export Law.
You agree to comply fully with all export laws and regulations to ensure that neither the Software nor any technical data related thereto nor any direct product thereof are exported or re-exported directly or indirectly in violation of, or used for any purposes prohibited by, such laws and regulations.
13. Choice of Law and Dispute Resolution.
1 Choice of Law. This Agreement will be governed by and construed in accordance with the laws of France, without regard to or application of conflict of laws rules or principles. The United Nations Convention on Contracts for the International Sale of Goods will not apply.
2 Arbitration of Disputes. Except as set forth below in Section 13(5), any dispute arising out of or in connection with this Agreement, including any disputes regarding the existence, validity or termination thereof, shall be settled by arbitration.
3 Arbitration Rules. The parties agree to arbitrate all disputes by simplified arbitration arranged by The French Institute of Arbitration in accordance with the rules of simplified arbitration procedure adopted by The French Institute of Arbitration and in force at the time when such proceedings are commenced.
4 Class Action Waiver. The parties further agree that any arbitration shall be conducted in their individual capacities only and not as a class action or other representative action, and the parties expressly waive their right to file a class action or seek relief on a class basis. YOU AND WASSA AGREE THAT EACH MAY BRING CLAIMS AGAINST THE OTHER ONLY IN YOUR OR ITS INDIVIDUAL CAPACITY, AND NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY PURPORTED CLASS OR REPRESENTATIVE PROCEEDING. If any court or arbitrator determines that the class action waiver set forth in this paragraph is void or unenforceable for any reason or that an arbitration can proceed on a class basis, then the arbitration provision set forth above shall be deemed null and void in its entirety and the parties shall be deemed to have not agreed to arbitrate disputes.
5 Arbitration Exceptions. Notwithstanding the parties agreement to resolve all disputes through arbitration, either party may bring an action in court: (a) to seek injunctive relief or to enforce its intellectual property rights (“intellectual property rights” means patents, copyrights, moral rights, trademarks, and trade secrets, but not privacy or publicity rights), including without limitation to seek injunctive relief; or (b) in cases that do not involve intellectual property rights, to seek temporary, preliminary or other expedited or provisional injunctive relief (but not money damages). If the parties have an intellectual property rights dispute, you and Wassa agree to submit to the personal and exclusive jurisdiction of and venue the courts located in Paris, France. The parties agree to accept service of process by mail, and hereby waive any and all jurisdictional and venue defenses otherwise available.
14. General.
This Agreement is the complete and exclusive understanding and agreement between the parties regarding its subject matter, and supersedes all proposals, understandings or communications between the parties, oral or written, regarding its subject matter, unless you and Wassa have executed a separate agreement governing use of the Software. The English language version of this Agreement is legally binding in case of any inconsistencies between the English version and any translations. Any terms or conditions contained in your purchase order or other ordering document that are inconsistent with or in addition to the terms and conditions of this Agreement are hereby rejected by Wassa and will be deemed null. You may not assign or transfer this Agreement or any rights granted hereunder, by operation of law or otherwise, without Wassas prior written consent, and any attempt by you to do so, without such consent, will be void. Without limiting the generality of the foregoing, if you are an employee of a Legal Entity, you may not assign or transfer this Agreement or any rights granted hereunder to your employer without Wassas prior written consent, and any attempt by you to do so, without such consent, will be void. Except as expressly set forth in this Agreement, the exercise by either party of any of its remedies under this Agreement will be without prejudice to its other remedies under this Agreement or otherwise. All notices or approvals required or permitted under this Agreement will be in writing and delivered by confirmed facsimile transmission, by overnight delivery service, or by certified mail, and in each instance will be deemed given upon receipt. All notices or approvals will be sent to the addresses set forth in the applicable ordering document or invoice or to such other address as may be specified by either party to the other in accordance with this section. The failure by either party to enforce any provision of this Agreement will not constitute a waiver of future enforcement of that or any other provision. Any waiver, modification or amendment of any provision of this Agreement will be effective only if in writing and signed by authorized representatives of both parties. If any provision of this Agreement is held to be unenforceable or invalid that provision will be enforced to the maximum extent possible and the other provisions will remain in full force and effect.
15. Definitions.
“Commercial Entity” means any company, corporation, limited liability company, general partnership, limited partnership, limited liability partnership, proprietorship, joint venture or other form of business organization, excluding any government, non-profit, educational or academic institution.
“Gambling Activities” means any gambling product or service offered in any market or application that is regulated by any local, state or national authority and requires a gambling license.
“Legal Entity” means any Commercial Entity, Non-Commercial Entity or Sole Proprietor.
“Licensee Content” means games, applications, software or other content that you develop with the Software.
“Non-Commercial Entity” means any government, non-profit, educational or academic institution, including but not limited to any primary or secondary school, vocational school, college or university.
“Software” means all versions and updates of all the Blurit software products identified on Blurit website.
“Sole Proprietor” means any Commercial Entity that is owned or controlled by a single individual, with no other partners or employees.
“Blurit” means the version of the Software available to commercial or non-commercial entities.

20
Package.swift Normal file
View File

@ -0,0 +1,20 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "Blurit",
platforms: [
.iOS(.v13)
],
products: [
.library(
name: "Blurit",
targets: ["Blurit_SDK"])
],
targets: [
.binaryTarget(
name: "Blurit_SDK",
path: "Blurit_SDK.xcframework"
)
]
)

108
README.md Normal file
View File

@ -0,0 +1,108 @@
# Blurit
[![Version](https://img.shields.io/cocoapods/v/Blurit?style=flat)](http://cocoapods.org/pods/Blurit)
[![License](https://img.shields.io/cocoapods/l/Blurit?style=flat)](http://cocoapods.org/pods/Blurit)
[![Platform](https://img.shields.io/cocoapods/p/Blurit?style=flat)](http://cocoapods.org/pods/Blurit)
<a href="https://swift.org/package-manager/"><img src="https://img.shields.io/badge/SPM-supported-Green.svg?style=flat"></a>
Blurit is an SDK to anonymize picture and videos containing faces and car plates.<br>
For more information about Blurit you can visit our [website](http://blurit.io/library/ios).
## Installation
### CocoaPods
[CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) is the recommended way to add Blurit to your project.
1. Add a pod entry for Blurit to your *Podfile* :
```
pod 'Blurit_SDK'
```
2. Install the pod(s) by running `pod install`.
3. Include Blurit wherever you need it with `#import <Blurit/Blurit.h>` from Objective-C or `import Blurit` from Swift.
### Swift Package Manager
```swift
dependencies: [
.package(url: "https://github.com/wassafr/Blurit-ios.git", from: "1.0.0")
]
```
### Manual installation
1. Download the [latest code version](https://github.com/wassafr/Blurit-ios/raw/master/Blurit.zip) or add the repository as a git submodule to your git-tracked project.
2. Include Blurit wherever you need it with `#import <Blurit_SDK/Blurit_SDK.h>` from Objective-C or `import Blurit_SDK` from Swift.
## Usage
To run the example project just open it and run. The framework is already included.
Make sure you also see [Blurit documentation](https://services.wassa.io/api/global-documentation/).
**Attention :** To use the SDK, you need a License Key you can get on the [Blurit website](http://blurit.io)
The sample code is commented and show usage examples of the SDK.
###Basics
1. Add the following import to the top of the file :
```
import Blurit
```
2. Instantiate a Blurit object
``
bluritInstance = Blurit(licenceKey: "your license key", completion: nil)
```
3. Load the detection models in the Blurit instance
```
bluritInstance?.loadModels(completion: { (error) in
if let error = error {
print("❌ Cannot initialize Blurit \(error.localizedDescription)")
} else {
}
})
```
4. Make prediction from picture
```
BluritService.shared.bluritInstance?.detectObjectsAsync(sourceImage: image, completion: { firstCompletionResult in
/// Handle detected objects
})
``````
5. You can now use predictions to apply the blur
BluritService.shared.bluritInstance?.anonymizeAsync(sourceImage: image, predictionResult: predictionResult, completion: { secondCompletionResult in
/// Handle blurred picture
})
``````
## Requirements
- Xcode 13
- iOS 13
## License
Blurit is available under a commercial license. See the LICENSE file for more info.
## Author
Wassa, contact@wassa.fr

219
index.html Normal file
View File

@ -0,0 +1,219 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Blurit-ios by wassafr</title>
<link rel="stylesheet" href="stylesheets/styles.css">
<link rel="stylesheet" href="stylesheets/github-light.css">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<header>
<h1>Blurit-ios</h1>
<p>Blurit is an SDK allowing mobile and embedded apps to detect face criterias of people located in front of a camera, by analyzing the video feed in realtime.</p>
<p class="view"><a href="https://github.com/wassafr/Blurit-ios">View the Project on GitHub <small>wassafr/Blurit-ios</small></a></p>
<ul>
<li><a href="https://github.com/wassafr/Blurit-ios/zipball/master">Download <strong>ZIP File</strong></a></li>
<li><a href="https://github.com/wassafr/Blurit-ios/tarball/master">Download <strong>TAR Ball</strong></a></li>
<li><a href="https://github.com/wassafr/Blurit-ios">View On <strong>GitHub</strong></a></li>
</ul>
</header>
<section>
<h1>
<a id="Blurit" class="anchor" href="#Blurit" aria-hidden="true"><span class="octicon octicon-link"></span></a>Blurit</h1>
<p><a href="http://cocoapods.org/pods/Blurit"><img src="https://img.shields.io/cocoapods/v/Blurit.svg?style=flat" alt="Version"></a>
<a href="http://cocoapods.org/pods/Blurit"><img src="https://img.shields.io/cocoapods/l/Blurit.svg?style=flat" alt="License"></a>
<a href="http://cocoapods.org/pods/Blurit"><img src="https://img.shields.io/cocoapods/p/Blurit.svg?style=flat" alt="Platform"></a></p>
<p>Blurit is an SDK allowing mobile apps to detect face criterias of people by analyzing the front video feed in realtime. Blurit is able to track multiple faces and then detect gender, some emotions, age range and accessories, for each detected face. For more <a href="http://face-lytics.com">informations</a>. You can download a sample application on the <a href="https://itunes.apple.com/ai/app/Blurit/id997764123">appstore</a> to see usage exemples for the sdk</p>
<h2>
<a id="installation" class="anchor" href="#installation" aria-hidden="true"><span class="octicon octicon-link"></span></a>Installation</h2>
<h3>
<a id="cocoapods" class="anchor" href="#cocoapods" aria-hidden="true"><span class="octicon octicon-link"></span></a>Cocoapods</h3>
<p><a href="http://www.cocoapods.org">CocoaPods</a> is the recommended way to add CaptchaFace to your project.</p>
<ol>
<li>Add a pod entry for Blurit to your <em>Podfile</em> :</li>
</ol>
<div class="highlight highlight-ruby"><pre>pod <span class="pl-s"><span class="pl-pds">"</span>Blurit<span class="pl-pds">"</span></span></pre></div>
<ol>
<li>Install the pod(s) by running <code>pod install</code>.</li>
<li>Include Blurit wherever you need it with <code>#import &lt;Blurit/Blurit.h&gt;</code> from Objective-C or <code>import Blurit</code> from Swift.</li>
<li>The library embeded in the cocoapods is compiled in debug mode to allow you to attach the debugger while developement. A release version of the library is available in the <strong>Pod/lib</strong> directory of the <a href="https://github.com/wassafr/Blurit-ios/archive/master.zip">following archive</a> if you want better performances in your release build </li>
</ol>
<h3>
<a id="manual-installation" class="anchor" href="#manual-installation" aria-hidden="true"><span class="octicon octicon-link"></span></a>Manual installation</h3>
<ol>
<li>Download the <a href="https://github.com/wassafr/Blurit-ios/archive/master.zip">latest code version</a> or add the repository as a git submodule to your git-tracked project.</li>
<li>Drag and drop the <strong>Pod</strong> directory from the archive in your project navigator. Make sure to select <em>Copy items</em> when asked if you extracted the code archive outside of your project.</li>
<li>Under <code>Pod/lib</code> there is 2 versions of the library, you need to add to your target only the one you need (wether you ar debugging or making a release)</li>
<li>Download the <a href="http://sourceforge.net/projects/opencvlibrary/files/opencv-ios/2.4.11/opencv2.framework.zip/download">opencv library</a> and drag and drop the opencv2.framework in your project navigator.</li>
<li>Add the opencv dependancies in your project properties in <em>Build Phases</em> &gt; <em>Link with libraries</em> :
<ul>
<li>libstdc++</li>
<li>Accelerate</li>
<li>AssetsLibrary</li>
<li>AVFoundation</li>
<li>CoreGraphics</li>
<li>CoreImage</li>
<li>CoreMedia</li>
<li>CoreVideo</li>
<li>Foundation</li>
<li>QuartzCore</li>
<li>ImageIO</li>
<li>MobileCoreServices</li>
<li>UIKit</li>
</ul>
</li>
<li>Include Blurit wherever you need it with <code>#import "Blurit.h"</code> from Objective-C or <code>import Blurit</code> from Swift.</li>
</ol>
<h2>
<a id="usage" class="anchor" href="#usage" aria-hidden="true"><span class="octicon octicon-link"></span></a>Usage</h2>
<p>To run the example project, clone the repo, and run <code>pod install</code> from the Example directory first. With <a href="http://www.cocoapods.org">CocoaPods</a> , you can run <code>pod try Blurit</code>
from the command line.</p>
<p>Make sure you also see <a href="http://cocoadocs.org/docsets/Faelytics">Blurit documentation on Cocoadocs</a>.</p>
<p><strong>Attention :</strong> To use the SDK, you need a API key that you can get for free on the <a href="http://face-lytics.com">Blurit website</a></p>
<p>The sample code is commented and show usage exemples of the SDK.</p>
<h3>
<a id="basics" class="anchor" href="#basics" aria-hidden="true"><span class="octicon octicon-link"></span></a>Basics</h3>
<ol>
<li>
<p>Add the following import to the top of the file or the bringing header for swift:</p>
<pre><code>#import &lt;Blurit/Blurit.h&gt;
</code></pre>
<p>The main sdk entry point is the FLYCaptureManager object.You have to keep a strong reference on the object while the session is running. You will need a new license request at each FLYCaptureManager creation. It's recomanded to create a new FLYCaptureManager for each session.</p>
</li>
<li>
<p>Optional : If the entire interface is based on Blurit, you can check if the device can run Blurit prior to show any Blurit related UI :</p>
<div class="highlight highlight-objc"><pre> <span class="pl-k">if</span>([FLYCaptureManager <span class="pl-c1">deviceSupportsBlurit</span>])
{
<span class="pl-c">//goto step 3-4</span>
}
<span class="pl-k">else</span>
{
<span class="pl-c">//fallback if the device can't use Blurit</span>
}</pre></div>
</li>
<li>
<p>Optional : If the entire interface is based on Blurit, you can check if you are authorised to launch Blurit prior to show any Blurit related UI. You need an apikey to lauch the sdk. You can visite <a href="http://face-lytics.com">Blurit website</a> to get a free demo key :</p>
<div class="highlight highlight-objc"><pre>
self.currentManager = [FLYCaptureManager <span class="pl-c1">alloc</span>] init]
[<span class="pl-v">self</span>.currentManager <span class="pl-c1">requestLicenceAuthorisation:</span><span class="pl-s"><span class="pl-pds">@"</span>&lt;your_key&gt;<span class="pl-pds">"</span></span> <span class="pl-c1">completion:</span>^(<span class="pl-c1">NSError</span> *error) {
<span class="pl-k">if</span>(!error)
{
<span class="pl-c">//show the Blurit related ui</span>
}
<span class="pl-k">else</span>
{
<span class="pl-c">//handle the error ( can be no camera, camera access not granted, device not powerfull enough or provided licence invalid</span>
}
}];</pre></div>
</li>
<li><p>Optional, you can show a Blurit related UI (ie. a view with the live video feed and an appropriate drawing). I you want to show a fullscreen preview, simply show a UIViewController which inherits from <code>FLYVideoPreviewViewController</code>. I you want to show a non fullScreen preview, you can attach an instance of <code>FLYVideoPreviewViewController</code>to the capture manager by using the function '- (NSError<em>)attachPreview:(FLYVideoPreviewViewController</em>)preview' (see the sample code for different exemples)</p></li>
<li>
<p>You have to start the sdk to begin analyzing faces. You can do it in the 'viewDidAppear' of the related ViewController for exemple
If you didn't perform step 3 :</p>
<div class="highlight highlight-objc"><pre>[<span class="pl-v">self</span>.currentManager <span class="pl-c1">startCapturewithDefaultCameraAndLicenceKey:</span><span class="pl-s"><span class="pl-pds">@"</span>kuc<span class="pl-pds">"</span></span> <span class="pl-c1">completion:</span>^(<span class="pl-c1">NSError</span> *error) {
<span class="pl-k">if</span>(error)
{
<span class="pl-c">//handle the error ( can be no camera, camera access not granted, device not powerfull enough or provided licence invalid</span>
}
<span class="pl-k">else</span>
{
<span class="pl-c">//start the face detection. By default only the camera feed is started</span>
[<span class="pl-v">self</span>.currentManager <span class="pl-c1">startFaceRecognition</span>];
<span class="pl-c">//step 6</span>
}
}];</pre></div>
<p>If you already performed step 3 :</p>
<div class="highlight highlight-objc"><pre>[<span class="pl-v">self</span>.currentManager <span class="pl-c1">startCapturewithDefaultCameraCompletion:</span>^(<span class="pl-c1">NSError</span> *error) {
<span class="pl-k">if</span>(error)
{
<span class="pl-c">//handle the error ( can be no camera, camera access not granted, device not powerfull enough or provided licence invalid</span>
}
<span class="pl-k">else</span>
{
<span class="pl-c">//start the face detection. By default only the camera feed is started</span>
[<span class="pl-v">self</span>.currentManager <span class="pl-c1">startFaceRecognition</span>];
<span class="pl-c">//step 6</span>
}
}];</pre></div>
<p>Look at the documentation of 'FLYCamera' to allow you to customize camera settings</p>
</li>
<li>
<p>Optional : You can assign a <code>FLYDetectionDelegate</code> to the capture manager to receive face related event and to know when the session is over to hide the related ui :</p>
<div class="highlight highlight-objc"><pre>[<span class="pl-v">self</span>.currentManager <span class="pl-c1">setDetectionDelegate:</span><span class="pl-k">id</span>&lt;FLYDetectionDelegate&gt;];</pre></div>
<p>You should implement the method <code>- (void)detectionDidStopAfterLicenceElapsedTime</code> to know when the session is over and do the appropriate ui staff.</p>
</li>
<li><p>When you're done, stop the session by calling the <code>[self.currentManager stopFaceRecognition]</code> method
`</p></li>
</ol>
<h2>
<a id="requirements" class="anchor" href="#requirements" aria-hidden="true"><span class="octicon octicon-link"></span></a>Requirements</h2>
<ul>
<li>Xcode 13</li>
<li>iOS 13</li>
<li>Devices responding to <code>[FLYCaptureManager deviceSupportsBlurit]</code>, typically iPhones from iphone 4s and iPads from the iPad3</li>
</ul>
<h2>
<a id="license" class="anchor" href="#license" aria-hidden="true"><span class="octicon octicon-link"></span></a>License</h2>
<p>Blurit is available under a commercial license. See the LICENSE file for more info.</p>
<h2>
<a id="author" class="anchor" href="#author" aria-hidden="true"><span class="octicon octicon-link"></span></a>Author</h2>
<p>Wassa, <a href="mailto:contact@wassa.fr">contact@wassa.fr</a></p>
</section>
<footer>
<p>This project is maintained by <a href="https://github.com/wassafr">wassafr</a></p>
<p><small>Hosted on GitHub Pages &mdash; Theme by <a href="https://github.com/orderedlist">orderedlist</a></small></p>
</footer>
</div>
<script src="javascripts/scale.fix.js"></script>
</body>
</html>

17
javascripts/scale.fix.js Normal file
View File

@ -0,0 +1,17 @@
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}

10
params.json Normal file
View File

@ -0,0 +1,10 @@
{"name":"Blurit-ios",
"tagline":"Blurit is an SDK to anonymize pictures and videos containing faces and car plates.",
"body":"# Blurit\r\n\r\n
[![Version](https://img.shields.io/cocoapods/v/Blurit.svg?style=flat)](http://cocoapods.org/pods/Blurit)\r\n[![License](https://img.shields.io/cocoapods/l/Blurit.svg?style=flat)](http://cocoapods.org/pods/Facelytics)\r\n[![Platform](https://img.shields.io/cocoapods/p/Facelytics.svg?style=flat)](http://cocoapods.org/pods/Facelytics)\r\n\r\n *Podfile* :\r\n\r\n```ruby\r\n
pod \"Blurit\"\r\n```\r\n\r\n2. Install the pod(s) by running `pod install`.\r\n3. Include Blurit wherever you need it with `#import <Facelytics/Facelytics.h>` from Objective-C or `import Facelytics` from Swift.\r\n4.
## Requirements\r\n\r\n
* Xcode 13\r\n* iOS 13\r\n
## License\r\n\r\nFacelytics is available under a commercial license. See the LICENSE file for more info.\r\n\r\n## Author\r\n\r\nWassa, contact@wassa.fr\r\n\r\n",
"google":"",
"note":"Don't delete this file! It's used internally to help with page regeneration."}

View File

@ -0,0 +1,116 @@
/*
Copyright 2014 GitHub Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.pl-c /* comment */ {
color: #969896;
}
.pl-c1 /* constant, markup.raw, meta.diff.header, meta.module-reference, meta.property-name, support, support.constant, support.variable, variable.other.constant */,
.pl-s .pl-v /* string variable */ {
color: #0086b3;
}
.pl-e /* entity */,
.pl-en /* entity.name */ {
color: #795da3;
}
.pl-s .pl-s1 /* string source */,
.pl-smi /* storage.modifier.import, storage.modifier.package, storage.type.java, variable.other, variable.parameter.function */ {
color: #333;
}
.pl-ent /* entity.name.tag */ {
color: #63a35c;
}
.pl-k /* keyword, storage, storage.type */ {
color: #a71d5d;
}
.pl-pds /* punctuation.definition.string, string.regexp.character-class */,
.pl-s /* string */,
.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,
.pl-sr /* string.regexp */,
.pl-sr .pl-cce /* string.regexp constant.character.escape */,
.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */,
.pl-sr .pl-sre /* string.regexp source.ruby.embedded */ {
color: #183691;
}
.pl-v /* variable */ {
color: #ed6a43;
}
.pl-id /* invalid.deprecated */ {
color: #b52a1d;
}
.pl-ii /* invalid.illegal */ {
background-color: #b52a1d;
color: #f8f8f8;
}
.pl-sr .pl-cce /* string.regexp constant.character.escape */ {
color: #63a35c;
font-weight: bold;
}
.pl-ml /* markup.list */ {
color: #693a17;
}
.pl-mh /* markup.heading */,
.pl-mh .pl-en /* markup.heading entity.name */,
.pl-ms /* meta.separator */ {
color: #1d3e81;
font-weight: bold;
}
.pl-mq /* markup.quote */ {
color: #008080;
}
.pl-mi /* markup.italic */ {
color: #333;
font-style: italic;
}
.pl-mb /* markup.bold */ {
color: #333;
font-weight: bold;
}
.pl-md /* markup.deleted, meta.diff.header.from-file */ {
background-color: #ffecec;
color: #bd2c00;
}
.pl-mi1 /* markup.inserted, meta.diff.header.to-file */ {
background-color: #eaffea;
color: #55a532;
}
.pl-mdr /* meta.diff.range */ {
color: #795da3;
font-weight: bold;
}
.pl-mo /* meta.output */ {
color: #1d3e81;
}

255
stylesheets/styles.css Normal file
View File

@ -0,0 +1,255 @@
@import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700);
body {
padding:50px;
font:14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
color:#777;
font-weight:300;
}
h1, h2, h3, h4, h5, h6 {
color:#222;
margin:0 0 20px;
}
p, ul, ol, table, pre, dl {
margin:0 0 20px;
}
h1, h2, h3 {
line-height:1.1;
}
h1 {
font-size:28px;
}
h2 {
color:#393939;
}
h3, h4, h5, h6 {
color:#494949;
}
a {
color:#39c;
font-weight:400;
text-decoration:none;
}
a small {
font-size:11px;
color:#777;
margin-top:-0.6em;
display:block;
}
.wrapper {
width:860px;
margin:0 auto;
}
blockquote {
border-left:1px solid #e5e5e5;
margin:0;
padding:0 0 0 20px;
font-style:italic;
}
code, pre {
font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal;
color:#333;
font-size:12px;
}
pre {
padding:8px 15px;
background: #f8f8f8;
border-radius:5px;
border:1px solid #e5e5e5;
overflow-x: auto;
}
table {
width:100%;
border-collapse:collapse;
}
th, td {
text-align:left;
padding:5px 10px;
border-bottom:1px solid #e5e5e5;
}
dt {
color:#444;
font-weight:700;
}
th {
color:#444;
}
img {
max-width:100%;
}
header {
width:270px;
float:left;
position:fixed;
}
header ul {
list-style:none;
height:40px;
padding:0;
background: #eee;
background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd));
background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
border-radius:5px;
border:1px solid #d2d2d2;
box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0;
width:270px;
}
header li {
width:89px;
float:left;
border-right:1px solid #d2d2d2;
height:40px;
}
header ul a {
line-height:1;
font-size:11px;
color:#999;
display:block;
text-align:center;
padding-top:6px;
height:40px;
}
strong {
color:#222;
font-weight:700;
}
header ul li + li {
width:88px;
border-left:1px solid #fff;
}
header ul li + li + li {
border-right:none;
width:89px;
}
header ul a strong {
font-size:14px;
display:block;
color:#222;
}
section {
width:500px;
float:right;
padding-bottom:50px;
}
small {
font-size:11px;
}
hr {
border:0;
background:#e5e5e5;
height:1px;
margin:0 0 20px;
}
footer {
width:270px;
float:left;
position:fixed;
bottom:50px;
}
@media print, screen and (max-width: 960px) {
div.wrapper {
width:auto;
margin:0;
}
header, section, footer {
float:none;
position:static;
width:auto;
}
header {
padding-right:320px;
}
section {
border:1px solid #e5e5e5;
border-width:1px 0;
padding:20px 0;
margin:0 0 20px;
}
header a small {
display:inline;
}
header ul {
position:absolute;
right:50px;
top:52px;
}
}
@media print, screen and (max-width: 720px) {
body {
word-wrap:break-word;
}
header {
padding:0;
}
header ul, header p.view {
position:static;
}
pre, code {
word-wrap:normal;
}
}
@media print, screen and (max-width: 480px) {
body {
padding:15px;
}
header ul {
display:none;
}
}
@media print {
body {
padding:0.4in;
font-size:12pt;
color:#444;
}
}