YPImagePicker

? Instagram-like image picker & filters for iOS

Github stars Tracking Chart

YPImagePicker

YPImagePicker is an instagram-like photo/video picker for iOS written in pure Swift. It is feature-rich and highly customizable to match your App's requirements.

Language: Swift 5
Version
Platform
Carthage compatible
codebeat badge
License: MIT
GitHub tag

Installation - Configuration - Usage - Languages - UI Customization

Give it a quick try :
pod repo update then pod try YPImagePicker

Those features are available just with a few lines of code!

Notable Features

? Library
? Photo
? Video
✂️ Crop
⚡️ Flash
? Filters
? Albums
? Multiple Selection
? Video Trimming & Cover selection
? Output image size
And many more...

Installation

Drop in the Classes folder to your Xcode project.
You can also use CocoaPods or Carthage.

Using CocoaPods

First be sure to run pod repo update to get the latest version available.

Add pod 'YPImagePicker' to your Podfile and run pod install. Also add use_frameworks! to the Podfile.

target 'MyApp'
pod 'YPImagePicker'
use_frameworks!

Using Carthage

Add github "Yummypets/YPImagePicker" to your Cartfile and run carthage update. If unfamiliar with Carthage then checkout their Getting Started section.

github "Yummypets/YPImagePicker"

Plist entries

In order for your app to access camera and photo libraries,
you'll need to ad these plist entries :

  • Privacy - Camera Usage Description (photo/videos)
  • Privacy - Photo Library Usage Description (library)
  • Privacy - Microphone Usage Description (videos)
<key>NSCameraUsageDescription</key>
<string>yourWording</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>yourWording</string>
<key>NSMicrophoneUsageDescription</key>
<string>yourWording</string>

Configuration

All the configuration endpoints are in the YPImagePickerConfiguration struct.
Below are the default value for reference, feel free to play around :)

var config = YPImagePickerConfiguration()
// [Edit configuration here ...]
// Build a picker with your configuration
let picker = YPImagePicker(configuration: config)

General

config.isScrollToChangeModesEnabled = true
config.onlySquareImagesFromCamera = true
config.usesFrontCamera = false
config.showsPhotoFilters = true
config.showsVideoTrimmer = true
config.shouldSaveNewPicturesToAlbum = true
config.albumName = "DefaultYPImagePickerAlbumName"
config.startOnScreen = YPPickerScreen.photo
config.screens = [.library, .photo]
config.showsCrop = .none
config.targetImageSize = YPImageSize.original
config.overlayView = UIView()
config.hidesStatusBar = true
config.hidesBottomBar = false
config.preferredStatusBarStyle = UIStatusBarStyle.default
config.bottomMenuItemSelectedColour = UIColor(r: 38, g: 38, b: 38)
config.bottomMenuItemUnSelectedColour = UIColor(r: 153, g: 153, b: 153)
config.filters = [DefaultYPFilters...]
config.maxCameraZoomFactor = 1.0

Library

config.library.options = nil
config.library.onlySquare = false
config.library.isSquareByDefault = true
config.library.minWidthForItem = nil
config.library.mediaType = YPlibraryMediaType.photo
config.library.defaultMultipleSelection = false
config.library.maxNumberOfItems = 1
config.library.minNumberOfItems = 1
config.library.numberOfItemsInRow = 4
config.library.spacingBetweenItems = 1.0
config.library.skipSelectionsGallery = false
config.library.preselectedItems = nil

Video

config.video.compression = AVAssetExportPresetHighestQuality
config.video.fileType = .mov
config.video.recordingTimeLimit = 60.0
config.video.libraryTimeLimit = 60.0
config.video.minimumTimeLimit = 3.0
config.video.trimmerMaxDuration = 60.0
config.video.trimmerMinDuration = 3.0
config.gallery.hidesRemoveButton = false

Default Configuration

// Set the default configuration for all pickers
YPImagePickerConfiguration.shared = config

// And then use the default configuration like so:
let picker = YPImagePicker()

Usage

First things first import YPImagePicker.

The picker only has one callback didFinishPicking enabling you to handle all the cases. Let's see some typical use cases ?

Single Photo

let picker = YPImagePicker()
picker.didFinishPicking { [unowned picker] items, _ in
    if let photo = items.singlePhoto {
        print(photo.fromCamera) // Image source (camera or library)
        print(photo.image) // Final image selected by the user
        print(photo.originalImage) // original image selected by the user, unfiltered
        print(photo.modifiedImage) // Transformed image, can be nil
        print(photo.exifMeta) // Print exif meta data of original image.
    }
    picker.dismiss(animated: true, completion: nil)
}
present(picker, animated: true, completion: nil)

Single video

// Here we configure the picker to only show videos, no photos.
var config = YPImagePickerConfiguration()
config.screens = [.library, .video]
config.library.mediaType = .video

let picker = YPImagePicker(configuration: config)
picker.didFinishPicking { [unowned picker] items, _ in
    if let video = items.singleVideo {
        print(video.fromCamera)
        print(video.thumbnail)
        print(video.url)
    }
    picker.dismiss(animated: true, completion: nil)
}
present(picker, animated: true, completion: nil)

As you can see singlePhoto and singleVideo helpers are here to help you handle single media which are very common, while using the same callback for all your use-cases \o/

Multiple selection

To enable multiple selection make sure to set library.maxNumberOfItems in the configuration like so:

var config = YPImagePickerConfiguration()
config.library.maxNumberOfItems = 3
let picker = YPImagePicker(configuration: config)

Then you can handle multiple selection in the same callback you know and love :

picker.didFinishPicking { [unowned picker] items, cancelled in
    for item in items {
        switch item {
        case .photo(let photo):
            print(photo)
        case .video(let video):
            print(video)
        }
    }
    picker.dismiss(animated: true, completion: nil)
}

Handle Cancel event (if needed)

picker.didFinishPicking { [unowned picker] items, cancelled in
    if cancelled {
        print("Picker was canceled")
    }
    picker.dismiss(animated: true, completion: nil)
}

That's it !

Languages

?? English, ?? Spanish, ?? French ?? Russian, ?? Dutch, ?? Brazilian, ?? Turkish, ?? Arabic, ?? German, ?? Italian, ?? Japanese, ?? Chinese, ?? Indonesian, ?? Korean, ?? Traditional Chinese(Taiwan), ?? Vietnamese, ?? Thai.

If your language is not supported, you can still customize the wordings via the configuration.wordings api:

config.wordings.libraryTitle = "Gallery"
config.wordings.cameraTitle = "Camera"
config.wordings.next = "OK"

Better yet you can submit an issue or pull request with your Localizable.strings file to add a new language !

UI Customization

We tried to keep things as native as possible, so this is done mostly through native Apis.

let coloredImage = UIImage(color: .red)
UINavigationBar.appearance().setBackgroundImage(coloredImage, for: UIBarMetrics.default)
// UIImage+color helper https://stackoverflow.com/questions/26542035/create-uiimage-with-solid-color-in-swift
let attributes = [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 30, weight: .bold) ]
UINavigationBar.appearance().titleTextAttributes = attributes // Title fonts
UIBarButtonItem.appearance().setTitleTextAttributes(attributes, for: .normal) // Bar Button fonts
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.yellow ] // Title color
UINavigationBar.appearance().tintColor = .red // Left. bar buttons
config.colors.tintColor = .green // Right bar buttons (actions)

Original Project & Author

This project has been first inspired by Fusuma
Considering the big code, design changes and all the additional features added along the way, this moved form a fork to a standalone separate repo, also for discoverability purposes.
Original Fusuma author is ytakz

Core Team

Contributors ?

ezisazis,
hanikeddah,
tahaburak,
ajkolean,
Anarchoschnitzel,
Emil,
Rafael Damasceno,
cenkingunlugu
heitara
portellaa
Romixery
shotat

Special thanks to ihtiht for the cool looking logo!

They helped us one way or another ?

userdar,
Evgeniy,
MehdiMahdloo,
om-ha,
userdar,
ChintanWeapp,
eddieespinal,
viktorgardart,
gdelarosa,
cwestMobile,
Tinyik,
Vivekthakur647,
tomasbykowski,
artemsmikh,
theolof,
dongdong3344,
MHX792,
CIronfounderson,
Guerrix,
Zedd0202,
mohammadZ74,
SalmanGhumsani,
wegweiser6,
BilalAkram,
KazimAhmad,
JustinBeBoy,
SashaMeyer,
GShushanik,
Cez95,
Palando,
sebastienboulogne,
JigneshParekh7165,
Deepakepaisa,
AndreiBoariu,
nathankonrad1,
wawilliams003,
pngo-hypewell,
PawanManjani,
devender54321,
Didar1994,
relaxsus
restoflash

Dependency

YPImagePicker relies on prynt/PryntTrimmerView for provide video trimming and cover features. Big thanks to @HHK1 for making this open source :)

Obj-C support

Objective-C is not supported and this is not on our roadmap.
Swift is the future and dropping Obj-C is the price to pay to keep our velocity on this library :)

License

YPImagePicker is released under the MIT license.
See LICENSE for details.

Swift Version

  • Swift 3 -> version 1.2.0
  • Swift 4.1 -> version 3.4.1
  • Swift 4.2 -> version 3.5.2
    releases/tag/3.4.0)
  • Swift 5.0 -> version 4.0.0
  • Swift 5.1 -> version 4.1.2

Main metrics

Overview
Name With OwnerYummypets/YPImagePicker
Primary LanguageSwift
Program languageRuby (Language Count: 3)
Platform
License:MIT License
所有者活动
Created At2017-07-19 15:00:05
Pushed At2025-04-22 16:20:46
Last Commit At2025-04-22 19:20:32
Release Count49
Last Release Name5.3.0 (Posted on )
First Release Name1.2.0 (Posted on 2017-08-22 15:33:43)
用户参与
Stargazers Count4.4k
Watchers Count66
Fork Count1k
Commits Count0.9k
Has Issues Enabled
Issues Count574
Issue Open Count148
Pull Requests Count167
Pull Requests Open Count5
Pull Requests Close Count63
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private