avito-tech / Paparazzo

Custom iOS camera and photo picker with editing capabilities
MIT License
779 stars 82 forks source link
camera gallery hacktoberfest hacktoberfest2021 ios photopicker photos swift

Overview

Version License Build Status

Paparazzo is a component for picking and editing photos.

Key Features
:camera: Taking photos using camera
:iphone: Picking photos from user's photo library
:scissors: Photo cropping and rotation
:droplet: 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:

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
)

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
)

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
)

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