Custom iOS camera and photo picker with editing capabilities

Overview

Overview

Version License Build Status

Paparazzo is a component for picking and editing photos.

Key Features
πŸ“· Taking photos using camera
πŸ“± Picking photos from user's photo library
βœ‚οΈ Photo cropping and rotation
πŸ’§ Applying filters to photos

Demo

Contents

Installation

There are two options to install Paparazzo using CocoaPods.

Using Marshroute:

pod "Paparazzo"

or if you don't use Marshroute and prefer not to get it as an additional dependency:

pod "Paparazzo/Core"

Usage

You can use either the entire module or photo library exclusively.

Presenting entire module

Initialize module assembly using Paparazzo.AssemblyFactory (or Paparazzo.MarshrouteAssemblyFactory if you use Marshroute):

let factory = Paparazzo.AssemblyFactory()
let assembly = factory.mediaPickerAssembly()

Create view controller using assembly's module method:

let data = MediaPickerData(
    items: items,
    autocorrectionFilters: filters,
    selectedItem: items.last,
    maxItemsCount: maxItemsCount,
    cropEnabled: true,
    autocorrectEnabled: true,
    cropCanvasSize: cropCanvasSize
)

let viewController = assembly.module(
    data: data,
    routerSeed: routerSeed,    // omit this parameter if you're using Paparazzo.AssemblyFactory
    configure: configure
)

Method parameters:

  • items β€” array of photos that should be initially selected when module is presenter.
  • filters β€” array of filters that can be applied to photos.
  • selectedItem β€” selected photo. If set to nil or if items doesn't contain any photo with matching identifier, then the first photo in array will be selected.
  • maxItemsCount β€” maximum number of photos that user is allowed to pick.
  • cropEnabled β€” boolean flag indicating whether user can perform photo cropping.
  • autocorrectEnabled β€” boolean flag indicating whether user can apply filters to photo .
  • cropCanvasSize β€” maximum size of canvas when cropping photos. (see Memory constraints when cropping).
  • routerSeed β€” routerSeed provided by Marshroute.
  • configure β€” closure that allows you to provide module's additional parameters.

Additional parameters of MediaPicker module

Additional parameters is described in protocol MediaPickerModule:

  • setContinueButtonTitle(_:), setContinueButtonEnabled(_:) , setContinueButtonVisible(_:) and setContinueButtonStyle(_:) allow to customize "Continue" button text and availability.
  • setAccessDeniedTitle(_:), setAccessDeniedMessage(_:) and setAccessDeniedButtonTitle(_:) allow to customize "Access Deined" view texts.
  • setCropMode(_:) allow to customize photo crop behavior.
  • onItemsAdd is called when user picks items from photo library or takes a new photo using camera.
  • onItemUpdate is called after user performed cropping.
  • onItemAutocorrect is called after applying filter.
  • onItemMove is called after moving photo.
  • onItemRemove is called when user deletes photo.
  • onFinish and onCancel is called when user taps Continue and Close respectively.

Memory constraints when cropping

When cropping photo on devices with low RAM capacity your application can crash due to memory warning. It happens because in order to perform actual cropping we need to put a bitmap of the original photo in memory. To descrease a chance of crashing on older devices (such as iPhone 4 or 4s) we can scale the source photo beforehand so that it takes up less space in memory. cropCanvasSize is used for that. It specifies the size of the photo we should be targeting when scaling.

Presenting photo library

Initialize module assembly using Paparazzo.AssemblyFactory (or Paparazzo.MarshrouteAssemblyFactory if you use Marshroute):

let factory = Paparazzo.AssemblyFactory()
let assembly = factory.photoLibraryAssembly()

Create view controller using assembly's module method:

let viewController = assembly.module(
    selectedItems: selectedItems,
    maxSelectedItemsCount: maxSelectedItemsCount,
    routerSeed: routerSeed,    // omit this parameter if you're using Paparazzo.AssemblyFactory
    configure: configure
)
  • selectedItems β€” preselected photos (or nil).
  • maxItemsCount β€” maximum number of photos that user is allowed to pick.
  • routerSeed β€” routerSeed provided by Marshroute.
  • configure β€” closure used to provide additional module setup.

Presenting mask cropper

MaskCropper is a module which provides easy way to customize cropping experience. See CroppingOverlayProvider protocol to get more details.

Initialize module assembly using Paparazzo.AssemblyFactory (or Paparazzo.MarshrouteAssemblyFactory if you use Marshroute):

let factory = Paparazzo.AssemblyFactory()
let assembly = factory.maskCropperAssembly()

Create view controller using assembly's module method:

let data = MaskCropperData(
    imageSource: photo.image,
    cropCanvasSize: cropCanvasSize
)
let viewController = assembly.module(
    data: data,
    croppingOverlayProvider: croppingOverlayProvider,
    routerSeed: routerSeed,    // omit this parameter if you're using Paparazzo.AssemblyFactory
    configure: configure
)
  • imageSource β€” photo that should be cropped.
  • croppingOverlayProvider β€” provider from CroppingOverlayProvidersFactory.
  • routerSeed β€” routerSeed provided by Marshroute.
  • configure β€” closure used to provide additional module setup.

Presenting scanner

Scanner is a module which provides easy way to handle realtime stream from camera. See ScannerOutputHandler protocol to get more details.

Demo

Initialize module assembly using Paparazzo.AssemblyFactory (or Paparazzo.MarshrouteAssemblyFactory if you use Marshroute):

let factory = Paparazzo.AssemblyFactory()
let assembly = factory.scannerAssembly()

Create view controller using assembly's module method:

let data = ScannerData(
    initialActiveCameraType: .back,
    cameraCaptureOutputHandlers: []
)
let viewController = assembly.module(
    data: data,
    routerSeed: routerSeed,    // omit this parameter if you're using Paparazzo.AssemblyFactory
    configure: configure
)
  • initialActiveCameraType β€” preferred camera when starting the module (front or back).
  • cameraCaptureOutputHandlers β€” array of handlers that confirm the ScannerOutputHandler protocol.
  • routerSeed β€” routerSeed provided by Marshroute.
  • configure β€” closure used to provide additional module setup.

UI Customization

You can customize colors, fonts and icons used in photo picker. Just pass an instance of PaparazzoUITheme to the initializer of assembly factory.

var theme = PaparazzoUITheme()
theme.shutterButtonColor = .blue
theme.accessDeniedTitleFont = .boldSystemFont(ofSize: 17)
theme.accessDeniedMessageFont = .systemFont(ofSize: 17)
theme.accessDeniedButtonFont = .systemFont(ofSize: 17)
theme.cameraContinueButtonTitleFont = .systemFont(ofSize: 17)
theme.cancelRotationTitleFont = .boldSystemFont(ofSize: 14)

let assemblyFactory = Paparazzo.AssemblyFactory(theme: theme)

ImageSource

Photos picked by user via Paparazzo is provided to you either as MediaPickerItem (when using MediaPicker module) or as PhotoLibraryItem (when using PhotoLibrary module). Both of these enitities are just wrappers around ImageSource, which is a protocol that allows you to get different image representations regardless of where it comes from. To find out how to use it go to https://github.com/avito-tech/ImageSource

Localization

You can see the list of supported languages here. If you don't see your language, we encourage you to contribute to the project by creating pull request that adds Localizable.strings file for that language.

If you're not satisfied with a string that is provided by Paparazzo, you can override it in your project. Just add Paparazzo.strings to your main bundle. Override only the strings you need (you can see an example of this in PaparazzoExample project).

License

MIT

Comments
  • The passing images

    The passing images

    @prn @limarc @eshkinkot @dkostyrev @lahmatiy thanks for helping me out last type with the storyboard example but two more questions. Is there anyway to access the images taken by the camera because I plan on passing them to a new view controller

    enhancement question 
    opened by jackpaster 22
  • Saving images to server and extracting them

    Saving images to server and extracting them

    @prn @limarc @eshkinkot @dkostyrev @lahmatiy Hey guys, I love this project its great. I just have one problem. once I extract my images from my server and want to edit the images or change the images I have using the paparazzo camera, Do I convert all my images back and put them into an image source array and set it in items down below or what do I do. Thanks again.

    question 
    opened by Ahmedshubber 16
  • Fatal error: Not enough bits to represent the passed value

    Fatal error: Not enough bits to represent the passed value

    When i am cropping a photo and tap to the check/OK button then i get this error Fatal error: Not enough bits to represent the passed value

    public init<T: Hashable>(hashable: T) {
        self.init(int32Value: Int32(hashable.hashValue))
    }
    

    ImageRequestId.swift

    waiting-for-release 
    opened by Umity 9
  • Camera View is not appearing !

    Camera View is not appearing !

    I am using code snippets from storyboard example. Everything works fine except for camera view that is showing nothing(but a white background). The strange thing , that i take can take pictures. PS : Swift 4 , iOS 11 and i converted Paparazzo pod to swift 4 Any help ?

    opened by skander300 9
  • Crop isn't working

    Crop isn't working

    This pod is awesome but the crop doesn't seem to be working for me. When I click on the crop icon nothing happens on screen and I get this log:

    2018-06-17 02:46:43.291844+0100 AppName[2095:993923] [ImageManager] Unable to load image data, /var/mobile/Media/DCIM/100APPLE/IMG_0841.JPG

    Does anyone know why this is coming up?

    opened by jamesalester 8
  • pod install

    pod install

    @HiveHicks I'm trying to install the pods for the updated project but all im getting is the files from the old version. I did pod 'Paparazzo' and my minimum deployment target is iOS 9. What do you think could be the problem

    question 
    opened by jackpaster 6
  • Accessing all the images in ImageSource

    Accessing all the images in ImageSource

    @HiveHicks Hello, as I've said before this is a great project. Its the only easily editable photo/camera editing app which I like. But when a user clicks on the media picker to present the paparazzo camera and takes or selects all the photos he or she wants and then clicks the button. on that done button I am passing all 25 images in a segue to another view controller where it will then be accessed in a custom image slider. But I keep getting this error. "Could not cast value of type 'ImageSource.PHAssetImageSource' (0x10e9f17c8) to 'UIImage' (0x110e290b0)." could you please help me. Here is my code.

    Paparazzo view controller: screen shot 2017-03-29 at 8 59 28 pm

    `@IBAction private func showPhotoLibrary() { var theme = PaparazzoUITheme() theme.shutterButtonColor = UIColor.blue.cgColor theme.shutterButtonDisabledColor = UIColor.black.cgColor theme.accessDeniedTitleFont = .boldSystemFont(ofSize: 17) theme.accessDeniedMessageFont = .systemFont(ofSize: 17) theme.accessDeniedButtonFont = .systemFont(ofSize: 17) theme.cameraContinueButtonTitleFont = .systemFont(ofSize: 17) theme.cancelRotationTitleFont = .boldSystemFont(ofSize: 14) let assemblyFactory = Paparazzo.AssemblyFactory(theme: theme) let assembly = assemblyFactory.photoLibraryAssembly()

        let galleryController = assembly.module(
            selectedItems: [],
            maxSelectedItemsCount: 5,
            configuration: { [weak self] module in
                weak var module = module
                module?.onFinish = { result in
                    
                    if case let .selectedItems(photoLibraryItems) = result {
                        self?.photos = photoLibraryItems.map { $0.image }
                        self?.updateUI()
                        self?.performSegue(withIdentifier: "ShowNow", sender: self?.photos)
                    }
                }
            }
        )
        
        let navigationController = UINavigationController(rootViewController: galleryController)
        
        present(navigationController, animated: true, completion: nil)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "ShowNow") {
            let pivc: view2ViewController? = segue.destination as? view2ViewController
            
            pivc?.arrImages = photos
            // here images is the array of images
            
        }
    }`
    

    Photo slider view controller: screen shot 2017-03-29 at 8 59 20 pm

    `@IBOutlet weak var imgSlider: UIView! var passedPhotos: [ImageSource]? var arrImages = Array() fileprivate var sliderVc1: LIHSliderViewController!

    override func viewDidLoad() { super.viewDidLoad() let slider1: LIHSlider = LIHSlider(images: arrImages as! [UIImage]) I'm getting this error "Could not cast value of type 'ImageSource.PHAssetImageSource' (0x10e9f17c8) to 'UIImage' (0x110e290b0)." right here. Its a thread break error. So if you can show me how I can access all the images from the paparazzo view controller, I'd really appreciate it. Thanks `

    opened by Ahmedshubber 5
  • square image camera

    square image camera

    @HiveHicks Hey, so I want to use this camera to take and crop to square images. My question, does this camera already convert full screen images to square images, or do I have to do something or is there already a call i can make in the papparazo camera to make it a square camera. Thanks I really need a response for the next launch.

    opened by jackpaster 3
  • Passing images example

    Passing images example

    @HiveHicks I created an example on stack overflow for passing images. I think it may help explain what I tried to do and what the problem was. Here is the link. http://stackoverflow.com/questions/42855366/passing-uiimages-to-view-controller

    opened by Ahmedshubber 3
  • Fix app freeze when accessing photo library for the first time in iOS 15.2

    Fix app freeze when accessing photo library for the first time in iOS 15.2

    Fixes https://github.com/avito-tech/Paparazzo/issues/92.

    Steps to reproduce:

    1. Launch iOS 15.2 simulator and remove PaparazzoExample_NoMarshroute app if installed.
    2. Build and run PaparazzoExample_NoMarshroute on that simulator.
    3. Tap "Media Picker".

    Expected result: Media picker is presented.

    Actual result: Media picker is not presented, app is frozen (main thread is blocked forever).

    opened by HiveHicks 2
  • Crash on trying show paparazzoViewController

    Crash on trying show paparazzoViewController

    Hi, I just created empty project and add Paparazzo pod from 'develop' branch.

    Then I trying start project and it crashes.

    Here code of my ViewController

    import UIKit
    import Paparazzo
    
    class ViewController: UIViewController {
    
    	override func viewDidLoad() {
    		super.viewDidLoad()
    		showPicker()
    	}
    
    	private func showPicker() {
    		let viewController = PaparazzoFacade.paparazzoViewController(
    					theme: PaparazzoUITheme(),
    					parameters: MediaPickerData(
    						items: [],
    						maxItemsCount: 3
    					),
    					onFinish: { images in
    						debugPrint(images)
    					}
    				)
    
    				self.present(viewController, animated: true, completion: nil)
    	}
    }
    

    Here my Podfile

    source 'https://github.com/CocoaPods/Specs.git'
    platform :ios, '11.0'
    inhibit_all_warnings!
    
    target 'testPaparazzo' do
      use_frameworks!
    
      pod 'Paparazzo/Core', :git => 'https://github.com/avito-tech/Paparazzo.git', :branch => 'develop'
    end
    
    opened by spase84 2
  • App freeze when accessing the Photo library when app is 1st installed on iOS 15.2

    App freeze when accessing the Photo library when app is 1st installed on iOS 15.2

    Context: Using Xcode 13.2 and building on iOS 15.2 devices When installing the app for the 1st time on a device or simulator.

    https://developer.apple.com/forums/thread/696804

    Solution Before iOS 15.2 version we could register PHPhotoLibrary.shared().register(self) without authorization, in iOS 15.2 it is not possible, you will get an error. You have to request authorization(requestAuthorization(_:)) for register PHPhotoLibrary.shared().register(self).

    How to implement it?

    bug 
    opened by outsourcestudio 1
  • Failed to bind EAGLDrawable

    Failed to bind EAGLDrawable

    Hi, after a continuous use of the camera in mediapicker, at some point all the buttons are like stuck or disabled but the camera view keeps displaying normally. I get the following error in the log :

    Failed to bind EAGLDrawable: <CAEAGLLayer: 0x282b9fc60> to GL_RENDERBUFFER 2 Failed to make complete framebuffer object 8cd6

    Please, help me with this issue.

    Thanks in advance.

    opened by jcvelaguirre 2
  • Consider to replace

    Consider to replace "class" by "AnyObject"

    I noticed that protocols in Paparazzo are defined by class:

    public protocol PaparazzoPickerModule: class { ... }

    Have you any plans to replace "class" by "AnyObject" according to the Swift evolution proposal #0153?

    opened by vkaltyrin 0
Releases(5.0.0)
  • 5.0.0(Oct 2, 2020)

    • XCode 12, iOS 14 and Swift 5 support
    • Handle limited photo access mode
    • New UX flow in photo library v2
    • New camera screen with seamless transition to it from photo library
    • Photos taken inside the app are now saved to user's photo library
    Source code(tar.gz)
    Source code(zip)
  • 4.0.0(Oct 2, 2020)

    • Swift 4.2 support
    • Bumped deployment target to iOS 9
    • GPS metadata is now written to captured photo if the app is authorized to access it
    • Continue button can now be placed at the bottom of the screen
    • UI fixes for devices with safe areas
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Jan 31, 2019)

    • Redesigned photo library, added albums support (@HiveHicks)
    • Support localization (@hivehicks)
    • Add PaparazzoFacade for easy Paparazzo initialization (@hivehicks)
    • Support iPhone X (@erikstrottmann, @hivehicks)
    • Add ability to enable haptic feedback on photo reordering (@west0r)
    • Add scanner module with support for camera output handling (@khomTima)
    • Optimize photo library opening (@khomTima)
    • Bug fixes & improvements
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Oct 6, 2017)

    • Add support for photo filters (@khomTima)
    • Add support for mask cropping (@vkaltyrin)
    • Add support for photo reordering (@peskish)
    • Add support for cache cleaning (@CognitiveDisson)
    • Minor fixes and improvements
    Source code(tar.gz)
    Source code(zip)
Owner
avito.tech
avito.ru engineering team open source projects
avito.tech
DTPhotoViewerController - A fully customizable photo viewer ViewController to display single photo or collection of photos, inspired by Facebook photo viewer.

DTPhotoViewerController Example Demo video: https://youtu.be/aTLx4M4zsKk DTPhotoViewerController is very simple to use, if you want to display only on

Tung Vo 277 Dec 17, 2022
PixPic, a Photo Editing App

PixPic PixPic, a Photo Editing App Built by Our iOS Interns What's the best way to teach interns how to write an iOS app? Just let them do it! This ap

Yalantis 1.3k Dec 24, 2022
FMPhotoPicker is a modern, simple and zero-dependency photo picker with an elegant and customizable image editor

FMPhotoPicker is a modern, simple and zero-dependency photo picker with an elegant and customizable image editor Quick demo Batch select/deselect Smoo

Cong Nguyen 648 Dec 27, 2022
React-native-photo-editor - Photo editor using native modules for iOS and Android

?? Image editor using native modules for iOS and Android. Inherit from 2 available libraries, ZLImageEditor (iOS) and PhotoEditor (Android)

Baron Ha. 244 Jan 5, 2023
WLPhotoPicker - A multifunction photo picker for iOS

WLPhotoPicker Example To run the example project, clone the repo, and run pod in

Weang 20 Nov 25, 2022
FlaneurImagePicker is an iOS image picker that allows users to pick images from different sources (ex: user's library, user's camera, Instagram...). It's highly customizable.

FlaneurImagePicker is a highly customizable iOS image picker that allows users to pick images from different sources (ex: device's library, device's c

FlaneurApp 17 Feb 2, 2020
A photo gallery for iOS with a modern feature set. Similar features as the Facebook photo browser.

EBPhotoPages ”A photo gallery can become a pretty complex component of an app very quickly. The EBPhotoPages project demonstrates how a developer coul

Eddy Borja 1.7k Dec 8, 2022
A free, multiplatform SDK for real-time facial motion capture using blendshapes, and rigid head pose in 3D space from any RGB camera, photo, or video.

mocap4face by Facemoji mocap4face by Facemoji is a free, multiplatform SDK for real-time facial motion capture based on Facial Action Coding System or

Facemoji 592 Jan 1, 2023
CameraButton - A simple camera button that can be used for photo and video capturing

CameraButton A simple camera button that can be used for photo and video capturi

Erik Drobne 9 Dec 22, 2022
FacebookImagePicker is Facebook album photo picker written in Swift.

Features β€’ Installation β€’ Usage β€’ Translation β€’ License GBHFacebookImagePicker is Facebook's album photo picker written in Swift, built to provide a s

Florian Gabach 231 Dec 17, 2022
DGCropImage - A photo cropping tool which mimics Photo.app written by Swift

DGCropImage A photo cropping tool which mimics Photo.app written by Swift. This

donggyu 11 Jul 14, 2022
Photo-Sharing-App - Photo Sharing App With Swift

Photo Sharing App You can register and log in to this application and share your

Yağız Savran 2 Jun 14, 2022
The camera shoot a photo when animals apear in the frame

AutoCatDogCam The camera shoot a photo when animals apear in the frame. How to u

MLBoy 3 Feb 26, 2022
ImagePicker - selecting images from the photo albums, with allowed permissions /on real device accesing the camera

ImagePicker - selecting images from the photo albums, with allowed permissions /on real device accesing the camera, permission also needed/after picking an image it has the possibility to rename it

Pavel SurovΓ½ 0 Jan 26, 2022
Get a photo which has effects like the system camera’s Portrait mode (on compatible devices).

Blurring background like Portrait mode in the iPhone camera If we want to have the blurring effect like the Portrait mode in the iOS Camera app. What

Kien (Bradley) Hoang 4 Sep 20, 2022
Vision Camera πŸ“Έ The Camera library that sees the vision.

Vision Camera ?? The Camera library that sees the vision. npm i react-native-vision-camera npx pod-install Documentation Guides API Ex

Marc Rousavy 3.5k Jan 5, 2023
Image picker with custom crop rect for iOS written in Swift (Ported over from GKImagePicker)

WDImagePicker Ever wanted a custom crop area for the UIImagePickerController? Now you can have it with WDImagePicker. Just set your custom crop area a

Wu Di 96 Dec 19, 2022
πŸ“Έ iMessage-like, Image Picker Controller Provides custom features.

RAImagePicker Description RAImagePicker is a protocol-oriented framework that provides custom features from the built-in Image Picker Edit. Overview O

Rashed Al-Lahaseh 14 Aug 18, 2022
ImagePickerSheetController replicates the custom photo action sheet in iMessage.

ImagePickerSheetController About ImagePickerSheetController is a component that replicates the custom photo action sheet in iMessage. It's very simila

Laurin Brandner 1.5k Jan 3, 2023