{"id":1513,"url":"https://github.com/avito-tech/Paparazzo","last_synced_at":"2025-08-02T04:31:54.749Z","repository":{"id":41086438,"uuid":"83403884","full_name":"avito-tech/Paparazzo","owner":"avito-tech","description":"Custom iOS camera and photo picker with editing capabilities","archived":false,"fork":false,"pushed_at":"2025-07-28T09:27:36.000Z","size":20640,"stargazers_count":786,"open_issues_count":9,"forks_count":80,"subscribers_count":22,"default_branch":"master","last_synced_at":"2025-07-28T11:31:09.730Z","etag":null,"topics":["camera","gallery","hacktoberfest","hacktoberfest2021","ios","photopicker","photos","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avito-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-02-28T07:39:59.000Z","updated_at":"2025-07-18T06:22:22.000Z","dependencies_parsed_at":"2024-01-07T22:23:24.089Z","dependency_job_id":"a09d899c-5c95-47ca-8a71-d114a39b0cc3","html_url":"https://github.com/avito-tech/Paparazzo","commit_stats":{"total_commits":889,"total_committers":26,"mean_commits":34.19230769230769,"dds":"0.40157480314960625","last_synced_commit":"af9cfde0e154b725ecae5386055f78cd2cbe7168"},"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/avito-tech/Paparazzo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2FPaparazzo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2FPaparazzo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2FPaparazzo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2FPaparazzo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avito-tech","download_url":"https://codeload.github.com/avito-tech/Paparazzo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2FPaparazzo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268334614,"owners_count":24233793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["camera","gallery","hacktoberfest","hacktoberfest2021","ios","photopicker","photos","swift"],"created_at":"2024-01-05T20:15:48.225Z","updated_at":"2025-08-02T04:31:54.736Z","avatar_url":"https://github.com/avito-tech.png","language":"Swift","funding_links":[],"categories":["Media","Swift"],"sub_categories":["Image","Other free courses"],"readme":"## Overview\n\n![Version](https://cocoapod-badges.herokuapp.com/v/Paparazzo/badge.png)\n![License](https://img.shields.io/badge/license-MIT-blue.svg)\n[![Build Status](https://travis-ci.org/avito-tech/Paparazzo.svg?branch=master)](https://travis-ci.org/avito-tech/Paparazzo)\n\n**Paparazzo** is a component for picking and editing photos.\n\n|            | Key Features                             |\n|------------|------------------------------------------|\n| :camera:   | Taking photos using camera               |\n| :iphone:   | Picking photos from user's photo library |\n| :scissors: | Photo cropping and rotation              |\n| :droplet: | Applying filters to photos                |\n\n![Demo](PaparazzoDemo.gif)\n\n# Branches\n\nAt the current moment framework has the two branches for development (Literally because of SPM).\n- The first branch is `develop`. Use it for the open source app.\n- The second branch is `MA-4071-add-spm-support`. Use it for the Avito app.\nPlease contact with @gnikiriy to find more information.\n\nKeep in mind to push changes in two bracnhes.\n\n# Contents\n\n* [Installation](#installation)\n* [Usage](#usage)\n  * [Presenting entire module](#present-whole-module)\n    * [Additional parameters of MediaPicker module](#MediaPickerModule)\n    * [Memory constraints when cropping](#memory-constraints)\n  * [Presenting photo library](#present-gallery)\n  * [Presenting mask cropper](#present-maskCropper)\n  * [Presenting scanner](#present-scanner)\n  * [UI Customization](#ui-customization)\n* [ImageSource](#ImageSource)\n* [Localization](#localization)\n\n# \u003ca name=\"installation\" /\u003eInstallation\nThere are two options to install Paparazzo using [CocoaPods](http://cocoapods.org).\n\nUsing [Marshroute](https://github.com/avito-tech/Marshroute):\n\n```ruby\npod \"Paparazzo\"\n```\n\nor if you don't use Marshroute and prefer not to get it as an additional dependency:\n\n```ruby\npod \"Paparazzo/Core\"\n```\n\n# \u003ca name=\"usage\" /\u003eUsage\nYou can use either the entire module or photo library exclusively.\n\n## \u003ca name=\"present-whole-module\" /\u003ePresenting entire module\nInitialize module assembly using `Paparazzo.AssemblyFactory` (or `Paparazzo.MarshrouteAssemblyFactory` if you use [Marshroute](https://github.com/avito-tech/Marshroute)):\n```swift\nlet factory = Paparazzo.AssemblyFactory()\nlet assembly = factory.mediaPickerAssembly()\n```\nCreate view controller using assembly's `module` method:\n```swift\nlet data = MediaPickerData(\n    items: items,\n    autocorrectionFilters: filters,\n    selectedItem: items.last,\n    maxItemsCount: maxItemsCount,\n    cropEnabled: true,\n    autocorrectEnabled: true,\n    cropCanvasSize: cropCanvasSize\n)\n\nlet viewController = assembly.module(\n    data: data,\n    routerSeed: routerSeed,    // omit this parameter if you're using Paparazzo.AssemblyFactory\n    configure: configure\n)\n```\nMethod parameters:\n* _items_ — array of photos that should be initially selected when module is presenter.\n* _filters_ — array of filters that can be applied to photos.\n* _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.\n* _maxItemsCount_ — maximum number of photos that user is allowed to pick.\n* _cropEnabled_ — boolean flag indicating whether user can perform photo cropping.\n* _autocorrectEnabled_ — boolean flag indicating whether user can apply filters to photo .\n* _cropCanvasSize_ — maximum size of canvas when cropping photos. (see [Memory constraints when cropping](#memory-constraints)).\n* _routerSeed_ — routerSeed provided by Marshroute.\n* _configure_ — closure that allows you to provide [module's additional parameters](#MediaPickerModule).\n\n### \u003ca name=\"MediaPickerModule\" /\u003eAdditional parameters of MediaPicker module\nAdditional parameters is described in protocol `MediaPickerModule`:\n\n* `setContinueButtonTitle(_:)`,  `setContinueButtonEnabled(_:)` , `setContinueButtonVisible(_:)` and `setContinueButtonStyle(_:)` allow to customize \"Continue\" button text and availability.\n* `setAccessDeniedTitle(_:)`,  `setAccessDeniedMessage(_:)`  and `setAccessDeniedButtonTitle(_:)` allow to customize \"Access Deined\" view texts.\n* `setCropMode(_:)` allow to customize photo crop behavior.\n* `onItemsAdd` is called when user picks items from photo library or takes a new photo using camera.\n* `onItemUpdate` is called after user performed cropping.\n* `onItemAutocorrect` is called after applying filter.\n* `onItemMove` is called after moving photo.\n* `onItemRemove` is called when user deletes photo.\n* `onFinish` and `onCancel` is called when user taps Continue and Close respectively.\n\n### \u003ca name=\"memory-constraints\" /\u003eMemory constraints when cropping\nWhen 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.\n\n## \u003ca name=\"present-gallery\" /\u003ePresenting photo library\nInitialize module assembly using `Paparazzo.AssemblyFactory` (or `Paparazzo.MarshrouteAssemblyFactory` if you use [Marshroute](https://github.com/avito-tech/Marshroute)):\n```swift\nlet factory = Paparazzo.AssemblyFactory()\nlet assembly = factory.photoLibraryAssembly()\n```\nCreate view controller using assembly's `module` method:\n```swift\nlet viewController = assembly.module(\n    selectedItems: selectedItems,\n    maxSelectedItemsCount: maxSelectedItemsCount,\n    routerSeed: routerSeed,    // omit this parameter if you're using Paparazzo.AssemblyFactory\n    configure: configure\n)\n```\n* _selectedItems_ — preselected photos (or `nil`).\n* _maxItemsCount_ — maximum number of photos that user is allowed to pick.\n* _routerSeed_ — routerSeed provided by Marshroute.\n* _configure_ — closure used to provide additional module setup.\n\n## \u003ca name=\"present-maskCropper\" /\u003ePresenting mask cropper\nMaskCropper is a module which provides easy way to customize cropping experience. See CroppingOverlayProvider protocol to get more details.\n\nInitialize module assembly using `Paparazzo.AssemblyFactory` (or `Paparazzo.MarshrouteAssemblyFactory` if you use [Marshroute](https://github.com/avito-tech/Marshroute)):\n```swift\nlet factory = Paparazzo.AssemblyFactory()\nlet assembly = factory.maskCropperAssembly()\n```\nCreate view controller using assembly's `module` method:\n```swift\nlet data = MaskCropperData(\n    imageSource: photo.image,\n    cropCanvasSize: cropCanvasSize\n)\nlet viewController = assembly.module(\n    data: data,\n    croppingOverlayProvider: croppingOverlayProvider,\n    routerSeed: routerSeed,    // omit this parameter if you're using Paparazzo.AssemblyFactory\n    configure: configure\n)\n```\n* _imageSource_ — photo that should be cropped.\n* _croppingOverlayProvider_ — provider from CroppingOverlayProvidersFactory.\n* _routerSeed_ — routerSeed provided by Marshroute.\n* _configure_ — closure used to provide additional module setup.\n\n## \u003ca name=\"present-scanner\" /\u003ePresenting scanner\nScanner is a module which provides easy way to handle realtime stream from camera. See ScannerOutputHandler protocol to get more details.\n\n\n![Demo](ScannerDemo.gif)\n\nInitialize module assembly using `Paparazzo.AssemblyFactory` (or `Paparazzo.MarshrouteAssemblyFactory` if you use [Marshroute](https://github.com/avito-tech/Marshroute)):\n```swift\nlet factory = Paparazzo.AssemblyFactory()\nlet assembly = factory.scannerAssembly()\n```\nCreate view controller using assembly's `module` method:\n```swift\nlet data = ScannerData(\n    initialActiveCameraType: .back,\n    cameraCaptureOutputHandlers: []\n)\nlet viewController = assembly.module(\n    data: data,\n    routerSeed: routerSeed,    // omit this parameter if you're using Paparazzo.AssemblyFactory\n    configure: configure\n)\n```\n* _initialActiveCameraType_ — preferred camera when starting the module (front or back).\n* _cameraCaptureOutputHandlers_ — array of handlers that confirm the  ScannerOutputHandler protocol.\n* _routerSeed_ — routerSeed provided by Marshroute.\n* _configure_ — closure used to provide additional module setup.\n\n## \u003ca name=\"ui-customization\" /\u003eUI Customization\nYou can customize colors, fonts and icons used in photo picker. Just pass an instance of `PaparazzoUITheme` to the initializer of assembly factory.\n\n```swift\nvar theme = PaparazzoUITheme()\ntheme.shutterButtonColor = .blue\ntheme.accessDeniedTitleFont = .boldSystemFont(ofSize: 17)\ntheme.accessDeniedMessageFont = .systemFont(ofSize: 17)\ntheme.accessDeniedButtonFont = .systemFont(ofSize: 17)\ntheme.cameraContinueButtonTitleFont = .systemFont(ofSize: 17)\ntheme.cancelRotationTitleFont = .boldSystemFont(ofSize: 14)\n\nlet assemblyFactory = Paparazzo.AssemblyFactory(theme: theme)\n```\n\n# \u003ca name=\"ImageSource\" /\u003eImageSource\nPhotos 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\n\n# \u003ca name=\"localization\" /\u003eLocalization\nYou can see the list of supported languages [here](Paparazzo/Localization). 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.\n\nIf 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).\n\n# License\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favito-tech%2FPaparazzo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favito-tech%2FPaparazzo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favito-tech%2FPaparazzo/lists"}