├── .codecov.yml ├── .github └── FUNDING.yml ├── .gitignore ├── .swiftlint.yml ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── .travis.yml ├── Documentation ├── README_EN.md ├── RELEASE_NOTE.md └── RELEASE_NOTE_CN.md ├── HXPhotoPicker.podspec ├── HXPhotoPickerExample.entitlements ├── HXPhotoPickerExample.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── xcshareddata │ └── xcschemes │ ├── HXPhotoPicker.xcscheme │ ├── HXPhotoPickerExample.xcscheme │ └── SwiftUIExample.xcscheme ├── HXPhotoPickerExample.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── WorkspaceSettings.xcsettings ├── LICENSE ├── Objective-C ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-1024.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-83.5@2x.png │ │ ├── icon-20-ipad.png │ │ ├── icon-20@2x-ipad.png │ │ ├── icon-20@2x.png │ │ ├── icon-20@3x.png │ │ ├── icon-29-ipad.png │ │ ├── icon-29.png │ │ ├── icon-29@2x-ipad.png │ │ ├── icon-29@2x.png │ │ ├── icon-29@3x.png │ │ ├── icon-40.png │ │ ├── icon-40@2x.png │ │ └── icon-40@3x.png │ ├── Contents.json │ ├── camera_overturn.imageset │ │ ├── Contents.json │ │ └── camera_overturn@2x.png │ ├── hotweibo_back_icon.imageset │ │ ├── Contents.json │ │ └── hotweibo_back_icon@2x.png │ ├── hx_photo_edit_trash_close.imageset │ │ ├── Contents.json │ │ └── hx_photo_edit_trash_close@2x.png │ ├── hx_photo_edit_trash_open.imageset │ │ ├── Contents.json │ │ └── hx_photo_edit_trash_open@2x.png │ ├── wx_bg_image.imageset │ │ ├── Contents.json │ │ └── wx_bg_image@2x.png │ └── wx_head_icon.imageset │ │ ├── Contents.json │ │ └── wx_head_icon@2x.png ├── Classes │ ├── OCPickerExampleViewController.h │ ├── OCPickerExampleViewController.m │ ├── ViewController.h │ ├── ViewController.m │ └── assets │ │ ├── IMG_0168.GIF │ │ └── c81.mp4 ├── HXPhotoPickerExample-Bridging-Header.h ├── Info.plist ├── SwiftPhotoPicker │ ├── SwiftAssetURLResult.swift │ ├── SwiftPhotoAsset.swift │ ├── SwiftPicker.swift │ ├── SwiftPickerConfiguration.swift │ └── SwiftPickerResult.swift └── main.m ├── Package.swift ├── Podfile ├── Podfile.lock ├── Pods ├── Local Podspecs │ └── HXPhotoPicker.podspec.json ├── Manifest.lock ├── Pods.xcodeproj │ └── project.pbxproj └── Target Support Files │ ├── HXPhotoPicker │ ├── HXPhotoPicker-Info.plist │ ├── HXPhotoPicker-dummy.m │ ├── HXPhotoPicker-prefix.pch │ ├── HXPhotoPicker-umbrella.h │ ├── HXPhotoPicker.debug.xcconfig │ ├── HXPhotoPicker.modulemap │ ├── HXPhotoPicker.release.xcconfig │ └── ResourceBundle-HXPhotoPicker_Privacy-HXPhotoPicker-Info.plist │ ├── Pods-HXPhotoPickerExample │ ├── Pods-HXPhotoPickerExample-Info.plist │ ├── Pods-HXPhotoPickerExample-acknowledgements.markdown │ ├── Pods-HXPhotoPickerExample-acknowledgements.plist │ ├── Pods-HXPhotoPickerExample-dummy.m │ ├── Pods-HXPhotoPickerExample-frameworks.sh │ ├── Pods-HXPhotoPickerExample-umbrella.h │ ├── Pods-HXPhotoPickerExample.debug.xcconfig │ ├── Pods-HXPhotoPickerExample.modulemap │ └── Pods-HXPhotoPickerExample.release.xcconfig │ └── Pods-SwiftUIExample │ ├── Pods-SwiftUIExample-Info.plist │ ├── Pods-SwiftUIExample-acknowledgements.markdown │ ├── Pods-SwiftUIExample-acknowledgements.plist │ ├── Pods-SwiftUIExample-dummy.m │ ├── Pods-SwiftUIExample-frameworks.sh │ ├── Pods-SwiftUIExample-umbrella.h │ ├── Pods-SwiftUIExample.debug.xcconfig │ ├── Pods-SwiftUIExample.modulemap │ └── Pods-SwiftUIExample.release.xcconfig ├── README.md ├── Sources ├── HXPhotoPicker │ ├── Camera+Location │ │ └── CameraViewController+Location.swift │ ├── Camera │ │ ├── Config │ │ │ └── CameraConfiguration.swift │ │ ├── Controller │ │ │ ├── CameraController.swift │ │ │ ├── CameraControllerProtocol.swift │ │ │ ├── CameraManager.swift │ │ │ ├── CameraResultViewController.swift │ │ │ ├── CameraViewController+BottomView.swift │ │ │ ├── CameraViewController+Editor.swift │ │ │ ├── CameraViewController+Preview.swift │ │ │ ├── CameraViewController+Result.swift │ │ │ └── CameraViewController.swift │ │ ├── Model │ │ │ ├── CameraFilter.swift │ │ │ ├── CameraRenderer.swift │ │ │ └── DeviceOrientationHelper.swift │ │ ├── Util │ │ │ └── Camera+PhotoTools.swift │ │ └── View │ │ │ ├── CameraBottomView.swift │ │ │ ├── CameraNormalPreviewView.swift │ │ │ ├── CameraPreviewView.swift │ │ │ ├── PassThrough.metal │ │ │ └── PreviewMetalView.swift │ ├── Core │ │ ├── Config │ │ │ ├── HXImageViewProtocol.swift │ │ │ ├── ImageViewConfig.swift │ │ │ ├── PhotoDebugLogsConfig.swift │ │ │ ├── PhotoHUDConfig.swift │ │ │ ├── PhotoHUDProtocol.swift │ │ │ └── SelectBoxConfiguration.swift │ │ ├── Controller │ │ │ └── HXBaseViewController.swift │ │ ├── Extension │ │ │ ├── Core+AVAsset.swift │ │ │ ├── Core+Bundle.swift │ │ │ ├── Core+CALayer.swift │ │ │ ├── Core+CGFloat.swift │ │ │ ├── Core+Data.swift │ │ │ ├── Core+Dictionary.swift │ │ │ ├── Core+FileManager.swift │ │ │ ├── Core+LayerRTLFrame.swift │ │ │ ├── Core+NSObject.swift │ │ │ ├── Core+String.swift │ │ │ ├── Core+UIApplication.swift │ │ │ ├── Core+UICollectionView.swift │ │ │ ├── Core+UIColor.swift │ │ │ ├── Core+UIDevice.swift │ │ │ ├── Core+UIFont.swift │ │ │ ├── Core+UIImage.swift │ │ │ ├── Core+UIImageView.swift │ │ │ ├── Core+UILabel.swift │ │ │ ├── Core+UITableView.swift │ │ │ ├── Core+UIView.swift │ │ │ ├── Core+UIViewController.swift │ │ │ ├── Core+UIViewRTLFrame.swift │ │ │ └── Core+URL.swift │ │ ├── HXPhotoPicker.swift │ │ ├── Model │ │ │ ├── AppearanceStyle.swift │ │ │ ├── CustomLanguage.swift │ │ │ ├── ExportPreset.swift │ │ │ ├── HXLog.swift │ │ │ ├── ImageContentType.swift │ │ │ ├── IndicatorType.swift │ │ │ ├── LanguageType.swift │ │ │ └── PhotoPanGestureRecognizer.swift │ │ ├── Util │ │ │ ├── AssetPermissionsUtil.swift │ │ │ ├── AssetSaveUtil.swift │ │ │ ├── ImageResource.swift │ │ │ ├── PhotoManager+Download.swift │ │ │ ├── PhotoManager+Language.swift │ │ │ ├── PhotoManager.swift │ │ │ ├── PhotoTools+Alert.swift │ │ │ ├── PhotoTools+Camera.swift │ │ │ ├── PhotoTools+File.swift │ │ │ ├── PhotoTools.swift │ │ │ └── TextManager.swift │ │ └── View │ │ │ ├── ProgressHUD │ │ │ ├── ProgressCircleView.swift │ │ │ ├── ProgressCricleJoinView.swift │ │ │ ├── ProgressHUD.swift │ │ │ ├── ProgressImageView.swift │ │ │ └── ProgressIndefiniteView.swift │ │ │ ├── SelectBoxView.swift │ │ │ └── VideoPlayer │ │ │ ├── PlayButton.swift │ │ │ ├── SliderView.swift │ │ │ ├── VideoPlaySliderView.swift │ │ │ └── VideoPlayerView.swift │ ├── Editor+View │ │ ├── Extension │ │ │ ├── EditorView+AVAsset.swift │ │ │ ├── EditorView+CGFloat.swift │ │ │ ├── EditorView+CIImage.swift │ │ │ ├── EditorView+UIImage.swift │ │ │ └── EditorView+UIView.swift │ │ ├── ImageEditedResult.swift │ │ ├── Model │ │ │ ├── EditorModels.swift │ │ │ ├── EditorTypes.swift │ │ │ └── EditorVideoCompositor.swift │ │ ├── Util │ │ │ ├── EditorDrawTool.swift │ │ │ ├── EditorVideoTool.swift │ │ │ └── EditorView+PhotoTools.swift │ │ ├── VideoEditedResult.swift │ │ └── View │ │ │ ├── EditorAdjusterView+ContentView.swift │ │ │ ├── EditorAdjusterView+Croper.swift │ │ │ ├── EditorAdjusterView+Edit.swift │ │ │ ├── EditorAdjusterView+FrameView.swift │ │ │ ├── EditorAdjusterView+Mirror.swift │ │ │ ├── EditorAdjusterView+Rotate.swift │ │ │ ├── EditorAdjusterView+ScreenRotation.swift │ │ │ ├── EditorAdjusterView+ScrollView.swift │ │ │ ├── EditorAdjusterView+Video.swift │ │ │ ├── EditorAdjusterView.swift │ │ │ ├── EditorAdjusterViewProtocol.swift │ │ │ ├── EditorAudioAnimationView.swift │ │ │ ├── EditorCanvasView.swift │ │ │ ├── EditorContentView.swift │ │ │ ├── EditorControlView.swift │ │ │ ├── EditorDrawView.swift │ │ │ ├── EditorFrameView+Control.swift │ │ │ ├── EditorFrameView+VideoPlay.swift │ │ │ ├── EditorFrameView.swift │ │ │ ├── EditorMaskView.swift │ │ │ ├── EditorMosaicView.swift │ │ │ ├── EditorStickersContentView.swift │ │ │ ├── EditorStickersItemView.swift │ │ │ ├── EditorStickersTrashView.swift │ │ │ ├── EditorStickersView.swift │ │ │ ├── EditorVideoPlayerView.swift │ │ │ ├── EditorView+AdjusterView.swift │ │ │ ├── EditorView+GestureRecognizer.swift │ │ │ ├── EditorView+Public.swift │ │ │ ├── EditorView+ScrollView.swift │ │ │ ├── EditorView.swift │ │ │ └── EditorViewProtocol.swift │ ├── Editor │ │ ├── Config │ │ │ └── EditorConfiguration.swift │ │ ├── Controller │ │ │ ├── EditorChartletViewController.swift │ │ │ ├── EditorMaskListViewController.swift │ │ │ ├── EditorMusicListViewController.swift │ │ │ ├── EditorStickerTextViewController.swift │ │ │ ├── EditorViewController+Action.swift │ │ │ ├── EditorViewController+Await.swift │ │ │ ├── EditorViewController+Brush.swift │ │ │ ├── EditorViewController+Chartlet.swift │ │ │ ├── EditorViewController+EditorView.swift │ │ │ ├── EditorViewController+Filters.swift │ │ │ ├── EditorViewController+LoadAsset.swift │ │ │ ├── EditorViewController+Mosaic.swift │ │ │ ├── EditorViewController+Music.swift │ │ │ ├── EditorViewController+Processing.swift │ │ │ ├── EditorViewController+Ratio.swift │ │ │ ├── EditorViewController+Text.swift │ │ │ ├── EditorViewController+ToolsView.swift │ │ │ ├── EditorViewController+UINavigationController.swift │ │ │ ├── EditorViewController+VideoControl.swift │ │ │ ├── EditorViewController.swift │ │ │ └── EditorViewControllerDelegate.swift │ │ ├── EditedResult.swift │ │ ├── EditorAsset.swift │ │ ├── Extension │ │ │ └── Editor+CIImage.swift │ │ ├── Model │ │ │ ├── EditorChartlet.swift │ │ │ ├── EditorPlayAuido.swift │ │ │ ├── EditorType.swift │ │ │ ├── PhotoEditorFilter.swift │ │ │ └── VideoEditorMusic.swift │ │ ├── Protocol │ │ │ ├── EditorChartletListProtocol.swift │ │ │ └── EditorMaskListProtocol.swift │ │ ├── Transition │ │ │ └── EditorTransition.swift │ │ ├── Util │ │ │ └── Editor+PhotoTools.swift │ │ └── View │ │ │ ├── Brush │ │ │ ├── EditorBrushBlockView.swift │ │ │ ├── EditorBrushColorView.swift │ │ │ └── EditorBrushSizeView.swift │ │ │ ├── Chartlet │ │ │ ├── EditorChartletPreviewView.swift │ │ │ ├── EditorChartletViewCell.swift │ │ │ └── EditorChartletViewListCell.swift │ │ │ ├── CropSize │ │ │ ├── EditorMaskListViewCell.swift │ │ │ ├── EditorRatioToolView.swift │ │ │ ├── EditorRatioToolViewCell.swift │ │ │ └── EditorScaleView.swift │ │ │ ├── EditorCollectionView.swift │ │ │ ├── EditorToolsView.swift │ │ │ ├── ExpandButton.swift │ │ │ ├── Filter │ │ │ ├── EditorFilterEditView.swift │ │ │ ├── EditorFilterParameterView.swift │ │ │ └── EditorFiltersView.swift │ │ │ ├── Mosaic │ │ │ └── EditorMosaicToolView.swift │ │ │ ├── Text │ │ │ ├── EditorStickerTextView+CollectionView.swift │ │ │ ├── EditorStickerTextView+Delegate.swift │ │ │ ├── EditorStickerTextView+Draw.swift │ │ │ └── EditorStickerTextView.swift │ │ │ └── Video │ │ │ ├── EditorMusicLyricViewCell.swift │ │ │ ├── EditorMusicView.swift │ │ │ ├── EditorMusicViewCell.swift │ │ │ ├── EditorVideoControlMaskView.swift │ │ │ ├── EditorVideoControlView.swift │ │ │ ├── EditorVideoControlViewCell.swift │ │ │ └── EditorVolumeView.swift │ ├── Picker │ │ ├── AssetResult.swift │ │ ├── AssetURLResult.swift │ │ ├── Config │ │ │ ├── AlbumListConfiguration.swift │ │ │ ├── AlbumTitleViewConfiguration.swift │ │ │ ├── ArrowViewConfiguration.swift │ │ │ ├── EmptyViewConfiguration.swift │ │ │ ├── NotAuthorizedConfiguration.swift │ │ │ ├── PhotoAlbumControllerConfiguration.swift │ │ │ ├── PhotoListCellConfiguration.swift │ │ │ ├── PhotoListConfiguration.swift │ │ │ ├── PickerBottomViewConfiguration.swift │ │ │ ├── PickerConfiguration.swift │ │ │ ├── PreviewViewConfiguration.swift │ │ │ └── SystemCameraConfiguration.swift │ │ ├── Controller │ │ │ ├── Album │ │ │ │ ├── AlbumViewController.swift │ │ │ │ ├── PhotoAlbumViewController.swift │ │ │ │ └── PhotoMyAlbumViewController.swift │ │ │ ├── Browser │ │ │ │ └── PhotoBrowser.swift │ │ │ ├── Photo │ │ │ │ ├── PhotoBaseViewController.swift │ │ │ │ ├── PhotoPickerController+Internal.swift │ │ │ │ ├── PhotoPickerController+PHPhotoLibrary.swift │ │ │ │ ├── PhotoPickerController+PickerData.swift │ │ │ │ ├── PhotoPickerController+Transitioning.swift │ │ │ │ ├── PhotoPickerController.swift │ │ │ │ ├── PhotoPickerControllerProtocol.swift │ │ │ │ └── PhotoSplitViewController.swift │ │ │ ├── Picker │ │ │ │ ├── PhotoPickerFilterViewController.swift │ │ │ │ ├── PhotoPickerListViewController.swift │ │ │ │ ├── PhotoPickerPageViewController.swift │ │ │ │ ├── PhotoPickerViewController+AlbumView.swift │ │ │ │ ├── PhotoPickerViewController+Camera.swift │ │ │ │ ├── PhotoPickerViewController+Editor.swift │ │ │ │ ├── PhotoPickerViewController+FetchAsset.swift │ │ │ │ ├── PhotoPickerViewController+PhotoList.swift │ │ │ │ ├── PhotoPickerViewController+Preview.swift │ │ │ │ ├── PhotoPickerViewController+Toolbar.swift │ │ │ │ ├── PhotoPickerViewController.swift │ │ │ │ └── SystemCameraViewController.swift │ │ │ └── Preview │ │ │ │ ├── PhotoPeekViewController.swift │ │ │ │ ├── PhotoPreviewViewController+CollectionView.swift │ │ │ │ ├── PhotoPreviewViewController+Editor.swift │ │ │ │ ├── PhotoPreviewViewController+NavigationController.swift │ │ │ │ ├── PhotoPreviewViewController+SelectBox.swift │ │ │ │ ├── PhotoPreviewViewController+Toolbar.swift │ │ │ │ ├── PhotoPreviewViewController.swift │ │ │ │ └── PhotoPreviewViewControllerProtocol.swift │ │ ├── Data │ │ │ ├── PhotoFetchData.swift │ │ │ └── PhotoPickerData.swift │ │ ├── Extension │ │ │ ├── Picker+Array.swift │ │ │ ├── Picker+ConfigExtension.swift │ │ │ ├── Picker+Int.swift │ │ │ ├── Picker+PHAsset.swift │ │ │ ├── Picker+PHAssetCollection.swift │ │ │ ├── Picker+PhotoAsset.swift │ │ │ ├── Picker+UIImageView.swift │ │ │ └── Picker+UIViewController.swift │ │ ├── Model │ │ │ ├── AssetError.swift │ │ │ ├── LivePhotoError.swift │ │ │ ├── LocalAsset │ │ │ │ ├── LocalAsset.swift │ │ │ │ └── NetworkAsset.swift │ │ │ ├── PhotoAsset │ │ │ │ ├── PhotoAsset+Codable.swift │ │ │ │ ├── PhotoAsset+Editor.swift │ │ │ │ ├── PhotoAsset+Equatable.swift │ │ │ │ ├── PhotoAsset+FileSize.swift │ │ │ │ ├── PhotoAsset+Image.swift │ │ │ │ ├── PhotoAsset+Local.swift │ │ │ │ ├── PhotoAsset+Network.swift │ │ │ │ ├── PhotoAsset+Request.swift │ │ │ │ ├── PhotoAsset+URL.swift │ │ │ │ ├── PhotoAsset+Video.swift │ │ │ │ └── PhotoAsset.swift │ │ │ ├── PhotoAssetCollection.swift │ │ │ ├── PhotoError.swift │ │ │ ├── PickerManager.swift │ │ │ └── PickerTypes.swift │ │ ├── PickerResult.swift │ │ ├── PickerView │ │ │ ├── PhotoPickerSwitchLayout.swift │ │ │ ├── PhotoPickerView+Asset.swift │ │ │ ├── PhotoPickerView+Camera.swift │ │ │ ├── PhotoPickerView+Cell.swift │ │ │ ├── PhotoPickerView+CollectionView.swift │ │ │ ├── PhotoPickerView+Editor.swift │ │ │ ├── PhotoPickerView+Function.swift │ │ │ ├── PhotoPickerView+Preview.swift │ │ │ ├── PhotoPickerView.swift │ │ │ └── PhotoPickerViewProtocol.swift │ │ ├── Protocol │ │ │ ├── Fetch │ │ │ │ ├── PhotoFetchAsset.swift │ │ │ │ └── PhotoFetchAssetCollection.swift │ │ │ ├── Transition │ │ │ │ ├── PhotoBrowserAnimationTransitioning.swift │ │ │ │ ├── PhotoBrowserInteractiveTransition.swift │ │ │ │ ├── PhotoPickerControllerAnimationTransitioning.swift │ │ │ │ └── PhotoPickerControllerInteractiveTransition.swift │ │ │ └── UI │ │ │ │ ├── AlbumList │ │ │ │ ├── PhotoAlbumController.swift │ │ │ │ └── PhotoAlbumList.swift │ │ │ │ ├── PhotoControllerEvent.swift │ │ │ │ ├── PhotoDeniedAuthorization.swift │ │ │ │ ├── PhotoList │ │ │ │ ├── PhotoPickerList.swift │ │ │ │ ├── PhotoPickerListAssets.swift │ │ │ │ ├── PhotoPickerListCollectionView.swift │ │ │ │ ├── PhotoPickerListCondition.swift │ │ │ │ ├── PhotoPickerListConfig.swift │ │ │ │ ├── PhotoPickerListFectchCell.swift │ │ │ │ ├── PhotoPickerListSwipeSelect.swift │ │ │ │ └── PhotoPickerNavigationTitle.swift │ │ │ │ ├── PhotoNavigationItem.swift │ │ │ │ ├── PhotoPickerControllerFectch.swift │ │ │ │ ├── PhotoPickerDataStatus.swift │ │ │ │ └── ToolBar │ │ │ │ └── PhotoToolBar.swift │ │ ├── Transition │ │ │ ├── PhotoBrowserAnimator.swift │ │ │ ├── PhotoBrowserInteractiveAnimator.swift │ │ │ ├── PhotoPickerControllerAnimator.swift │ │ │ ├── PhotoPickerControllerInteractiveAnimator.swift │ │ │ ├── PickerInteractiveTransition.swift │ │ │ └── PickerTransition.swift │ │ ├── Util │ │ │ ├── AssetManager+AVAsset.swift │ │ │ ├── AssetManager+AVAssetExportSession.swift │ │ │ ├── AssetManager+Asset.swift │ │ │ ├── AssetManager+Image.swift │ │ │ ├── AssetManager+ImageData.swift │ │ │ ├── AssetManager+ImageURL.swift │ │ │ ├── AssetManager+LivePhoto.swift │ │ │ ├── AssetManager+LivePhotoURL.swift │ │ │ ├── AssetManager+PlayerItem.swift │ │ │ ├── AssetManager+VideoURL.swift │ │ │ ├── AssetManager.swift │ │ │ ├── Picker+LivePhotoTools.swift │ │ │ ├── Picker+PhotoManager.swift │ │ │ └── Picker+PhotoTools.swift │ │ └── View │ │ │ ├── Album │ │ │ ├── AlbumListView.swift │ │ │ ├── AlbumSectionHeaderView.swift │ │ │ ├── AlbumTitleView.swift │ │ │ └── PhotoAlbumHeaderView.swift │ │ │ ├── CaptureVideoPreviewView.swift │ │ │ ├── Cell │ │ │ ├── Album │ │ │ │ ├── AlbumViewBaseCell.swift │ │ │ │ ├── AlbumViewCell.swift │ │ │ │ ├── PhotoAlbumCollectionCell.swift │ │ │ │ ├── PhotoAlbumCollectionViewCell.swift │ │ │ │ └── PhotoAlbumViewCell.swift │ │ │ ├── PhotoLoadingView.swift │ │ │ ├── PhotoPickerBaseViewCell.swift │ │ │ ├── PhotoPickerLimitCell.swift │ │ │ ├── PhotoPickerSelectableViewCell.swift │ │ │ ├── PhotoPickerViewCell.swift │ │ │ ├── PhotoPickerWeChatViewCell.swift │ │ │ ├── PhotoPreviewViewCell.swift │ │ │ ├── PickerCameraViewCell.swift │ │ │ ├── PreviewLivePhotoViewCell.swift │ │ │ ├── PreviewPhotoViewCell.swift │ │ │ ├── PreviewVideoControlViewCell.swift │ │ │ └── PreviewVideoViewCell.swift │ │ │ ├── DeniedAuthorizationView.swift │ │ │ ├── Kit │ │ │ ├── ArrowView.swift │ │ │ ├── EmptyView.swift │ │ │ └── TickView.swift │ │ │ ├── PhotoImageCancelItemView.swift │ │ │ ├── PhotoPickerBottomNumberView.swift │ │ │ ├── PhotoPickerFilterItemView.swift │ │ │ ├── PhotoPickerFinishItemView.swift │ │ │ ├── PhotoPreviewContentLivePhotoView.swift │ │ │ ├── PhotoPreviewContentPhotoView.swift │ │ │ ├── PhotoPreviewContentVideoView.swift │ │ │ ├── PhotoPreviewContentViewProtocol.swift │ │ │ ├── PhotoPreviewVideoView.swift │ │ │ ├── PhotoTextCancelItemView.swift │ │ │ ├── PhotoThumbnailView.swift │ │ │ └── ToolBar │ │ │ ├── PhotoPermissionPromptView.swift │ │ │ ├── PhotoPreviewListView.swift │ │ │ ├── PhotoPreviewListViewCell.swift │ │ │ ├── PhotoPreviewListViewLayout.swift │ │ │ ├── PhotoPreviewSelectedView.swift │ │ │ ├── PhotoPreviewSelectedViewCell.swift │ │ │ ├── PhotoToolBarEmptyView.swift │ │ │ └── PhotoToolBarView.swift │ └── Resources │ │ ├── HXPhotoPicker.bundle │ │ ├── ar.lproj │ │ │ └── Localizable.strings │ │ ├── de.lproj │ │ │ └── Localizable.strings │ │ ├── en.lproj │ │ │ └── Localizable.strings │ │ ├── es.lproj │ │ │ └── Localizable.strings │ │ ├── fr.lproj │ │ │ └── Localizable.strings │ │ ├── id.lproj │ │ │ └── Localizable.strings │ │ ├── images │ │ │ ├── hx_camera_down_back@2x.png │ │ │ ├── hx_camera_down_back@3x.png │ │ │ ├── hx_camera_overturn@2x.png │ │ │ ├── hx_camera_overturn@3x.png │ │ │ ├── hx_editor_box_normal@2x.png │ │ │ ├── hx_editor_box_normal@3x.png │ │ │ ├── hx_editor_box_selected@2x.png │ │ │ ├── hx_editor_box_selected@3x.png │ │ │ ├── hx_editor_brush_color_custom@2x.png │ │ │ ├── hx_editor_brush_color_custom@3x.png │ │ │ ├── hx_editor_brush_repeal@2x.png │ │ │ ├── hx_editor_brush_repeal@3x.png │ │ │ ├── hx_editor_canvas_draw_redo@2x.png │ │ │ ├── hx_editor_canvas_draw_redo@3x.png │ │ │ ├── hx_editor_canvas_draw_undo@2x.png │ │ │ ├── hx_editor_canvas_draw_undo@3x.png │ │ │ ├── hx_editor_canvas_draw_undo_all@2x.png │ │ │ ├── hx_editor_canvas_draw_undo_all@3x.png │ │ │ ├── hx_editor_crop_mask_list@2x.png │ │ │ ├── hx_editor_crop_mask_list@3x.png │ │ │ ├── hx_editor_crop_scale_switch_left@2x.png │ │ │ ├── hx_editor_crop_scale_switch_left@3x.png │ │ │ ├── hx_editor_crop_scale_switch_left_selected@2x.png │ │ │ ├── hx_editor_crop_scale_switch_left_selected@3x.png │ │ │ ├── hx_editor_crop_scale_switch_right@2x.png │ │ │ ├── hx_editor_crop_scale_switch_right@3x.png │ │ │ ├── hx_editor_crop_scale_switch_right_selected@2x.png │ │ │ ├── hx_editor_crop_scale_switch_right_selected@3x.png │ │ │ ├── hx_editor_filter_edit_brightness@2x.png │ │ │ ├── hx_editor_filter_edit_brightness@3x.png │ │ │ ├── hx_editor_filter_edit_contrast@2x.png │ │ │ ├── hx_editor_filter_edit_contrast@3x.png │ │ │ ├── hx_editor_filter_edit_exposure@2x.png │ │ │ ├── hx_editor_filter_edit_exposure@3x.png │ │ │ ├── hx_editor_filter_edit_highlights@2x.png │ │ │ ├── hx_editor_filter_edit_highlights@3x.png │ │ │ ├── hx_editor_filter_edit_saturation@2x.png │ │ │ ├── hx_editor_filter_edit_saturation@3x.png │ │ │ ├── hx_editor_filter_edit_shadows@2x.png │ │ │ ├── hx_editor_filter_edit_shadows@3x.png │ │ │ ├── hx_editor_filter_edit_sharpen@2x.png │ │ │ ├── hx_editor_filter_edit_sharpen@3x.png │ │ │ ├── hx_editor_filter_edit_vignette@2x.png │ │ │ ├── hx_editor_filter_edit_vignette@3x.png │ │ │ ├── hx_editor_filter_edit_warmth@2x.png │ │ │ ├── hx_editor_filter_edit_warmth@3x.png │ │ │ ├── hx_editor_mosaic_brush_image@2x.png │ │ │ ├── hx_editor_mosaic_brush_image@3x.png │ │ │ ├── hx_editor_photo_crop@2x.png │ │ │ ├── hx_editor_photo_crop@3x.png │ │ │ ├── hx_editor_photo_mirror_horizontally@2x.png │ │ │ ├── hx_editor_photo_mirror_horizontally@3x.png │ │ │ ├── hx_editor_photo_mirror_vertically@2x.png │ │ │ ├── hx_editor_photo_mirror_vertically@3x.png │ │ │ ├── hx_editor_photo_rotate_left@2x.png │ │ │ ├── hx_editor_photo_rotate_left@3x.png │ │ │ ├── hx_editor_photo_rotate_right@2x.png │ │ │ ├── hx_editor_photo_rotate_right@3x.png │ │ │ ├── hx_editor_photo_text_normal@2x.png │ │ │ ├── hx_editor_photo_text_normal@3x.png │ │ │ ├── hx_editor_photo_text_selected@2x.png │ │ │ ├── hx_editor_photo_text_selected@3x.png │ │ │ ├── hx_editor_photo_tools_emoji@2x.png │ │ │ ├── hx_editor_photo_tools_emoji@3x.png │ │ │ ├── hx_editor_photo_tools_text@2x.png │ │ │ ├── hx_editor_photo_tools_text@3x.png │ │ │ ├── hx_editor_photo_trash_close@2x.png │ │ │ ├── hx_editor_photo_trash_close@3x.png │ │ │ ├── hx_editor_photo_trash_open@2x.png │ │ │ ├── hx_editor_photo_trash_open@3x.png │ │ │ ├── hx_editor_tool_mosaic_color@2x.png │ │ │ ├── hx_editor_tool_mosaic_color@3x.png │ │ │ ├── hx_editor_tool_mosaic_normal@2x.png │ │ │ ├── hx_editor_tool_mosaic_normal@3x.png │ │ │ ├── hx_editor_tools_chartle_album@2x.png │ │ │ ├── hx_editor_tools_chartle_album@3x.png │ │ │ ├── hx_editor_tools_filter@2x.png │ │ │ ├── hx_editor_tools_filter@3x.png │ │ │ ├── hx_editor_tools_filter_change@2x.png │ │ │ ├── hx_editor_tools_filter_change@3x.png │ │ │ ├── hx_editor_tools_filter_edit@2x.png │ │ │ ├── hx_editor_tools_filter_edit@3x.png │ │ │ ├── hx_editor_tools_filter_reset@2x.png │ │ │ ├── hx_editor_tools_filter_reset@3x.png │ │ │ ├── hx_editor_tools_graffiti@2x.png │ │ │ ├── hx_editor_tools_graffiti@3x.png │ │ │ ├── hx_editor_tools_mosaic@2x.png │ │ │ ├── hx_editor_tools_mosaic@3x.png │ │ │ ├── hx_editor_tools_music@2x.png │ │ │ ├── hx_editor_tools_music@3x.png │ │ │ ├── hx_editor_tools_play@2x.png │ │ │ ├── hx_editor_tools_play@3x.png │ │ │ ├── hx_editor_video_control_arrow_left@2x.png │ │ │ ├── hx_editor_video_control_arrow_left@3x.png │ │ │ ├── hx_editor_video_control_arrow_right@2x.png │ │ │ ├── hx_editor_video_control_arrow_right@3x.png │ │ │ ├── hx_editor_video_control_pause@2x.png │ │ │ ├── hx_editor_video_control_pause@3x.png │ │ │ ├── hx_editor_video_control_play@2x.png │ │ │ ├── hx_editor_video_control_play@3x.png │ │ │ ├── hx_editor_video_music_search@2x.png │ │ │ ├── hx_editor_video_music_search@3x.png │ │ │ ├── hx_editor_video_music_volume@2x.png │ │ │ ├── hx_editor_video_music_volume@3x.png │ │ │ ├── hx_editor_view_sticker_item_delete@2x.png │ │ │ ├── hx_editor_view_sticker_item_delete@3x.png │ │ │ ├── hx_editor_view_sticker_item_rotate@2x.png │ │ │ ├── hx_editor_view_sticker_item_rotate@3x.png │ │ │ ├── hx_editor_view_sticker_item_scale@2x.png │ │ │ ├── hx_editor_view_sticker_item_scale@3x.png │ │ │ ├── hx_photo_edit_pull_down@2x.png │ │ │ ├── hx_photo_edit_pull_down@3x.png │ │ │ ├── hx_photo_list_filter_any@2x.png │ │ │ ├── hx_photo_list_filter_any@3x.png │ │ │ ├── hx_photo_list_filter_edited@2x.png │ │ │ ├── hx_photo_list_filter_edited@3x.png │ │ │ ├── hx_photo_list_filter_gif@2x.png │ │ │ ├── hx_photo_list_filter_gif@3x.png │ │ │ ├── hx_photo_list_filter_livePhoto@2x.png │ │ │ ├── hx_photo_list_filter_livePhoto@3x.png │ │ │ ├── hx_photo_list_filter_photo@2x.png │ │ │ ├── hx_photo_list_filter_photo@3x.png │ │ │ ├── hx_photo_list_filter_video@2x.png │ │ │ ├── hx_photo_list_filter_video@3x.png │ │ │ ├── hx_picker_album_empty@2x.png │ │ │ ├── hx_picker_album_empty@3x.png │ │ │ ├── hx_picker_cell_photo_edit_icon@2x.png │ │ │ ├── hx_picker_cell_photo_edit_icon@3x.png │ │ │ ├── hx_picker_cell_video_edit_icon@2x.png │ │ │ ├── hx_picker_cell_video_edit_icon@3x.png │ │ │ ├── hx_picker_cell_video_icon@2x.png │ │ │ ├── hx_picker_cell_video_icon@3x.png │ │ │ ├── hx_picker_cell_video_play@2x.png │ │ │ ├── hx_picker_cell_video_play@3x.png │ │ │ ├── hx_picker_livePhoto@2x.png │ │ │ ├── hx_picker_livePhoto@3x.png │ │ │ ├── hx_picker_notAuthorized_close@2x.png │ │ │ ├── hx_picker_notAuthorized_close@3x.png │ │ │ ├── hx_picker_notAuthorized_close_dark@2x.png │ │ │ ├── hx_picker_notAuthorized_close_dark@3x.png │ │ │ ├── hx_picker_photoList_photograph@2x.png │ │ │ ├── hx_picker_photoList_photograph@3x.png │ │ │ ├── hx_picker_photoList_photograph_white@2x.png │ │ │ ├── hx_picker_photoList_photograph_white@3x.png │ │ │ ├── hx_picker_photo_icloud_mark@2x.png │ │ │ ├── hx_picker_photo_icloud_mark@3x.png │ │ │ ├── hx_picker_photolist_back@2x.png │ │ │ ├── hx_picker_photolist_back@3x.png │ │ │ ├── hx_picker_photolist_bottom_prompt@2x.png │ │ │ ├── hx_picker_photolist_bottom_prompt@3x.png │ │ │ ├── hx_picker_photolist_bottom_prompt_arrow@2x.png │ │ │ ├── hx_picker_photolist_bottom_prompt_arrow@3x.png │ │ │ ├── hx_picker_photolist_cancel@2x.png │ │ │ ├── hx_picker_photolist_cancel@3x.png │ │ │ ├── hx_picker_photolist_nav_filter_normal@2x.png │ │ │ ├── hx_picker_photolist_nav_filter_normal@3x.png │ │ │ ├── hx_picker_photolist_nav_filter_selected@2x.png │ │ │ ├── hx_picker_photolist_nav_filter_selected@3x.png │ │ │ ├── hx_picker_toolbar_select_cell_delete@2x.png │ │ │ └── hx_picker_toolbar_select_cell_delete@3x.png │ │ ├── ja.lproj │ │ │ └── Localizable.strings │ │ ├── ko.lproj │ │ │ └── Localizable.strings │ │ ├── metal │ │ │ └── hx_default.metallib │ │ ├── musics │ │ │ └── 天外来物 │ │ ├── pt.lproj │ │ │ └── Localizable.strings │ │ ├── ru.lproj │ │ │ └── Localizable.strings │ │ ├── th.lproj │ │ │ └── Localizable.strings │ │ ├── vi.lproj │ │ │ └── Localizable.strings │ │ ├── zh-Hans.lproj │ │ │ └── Localizable.strings │ │ └── zh-Hant.lproj │ │ │ └── Localizable.strings │ │ └── PrivacyInfo.xcprivacy ├── ImageView │ ├── GIFImageView.swift │ ├── KFImageView.swift │ └── SDImageView.swift └── Info.plist ├── Swift ├── AppDelegate.swift ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── hx_compose_delete.imageset │ │ ├── Contents.json │ │ └── hx_compose_delete@2x.png │ ├── hx_picker_add_img.imageset │ │ ├── Contents.json │ │ └── hx_picker_add_img@2x.png │ ├── hx_picker_cell_video_play.imageset │ │ ├── Contents.json │ │ └── hx_picker_cell_video_play@2x.png │ ├── hx_sticker_cover.imageset │ │ ├── Contents.json │ │ └── hx_sticker_cover@2x.png │ └── select_photo.imageset │ │ ├── Contents.json │ │ └── select_photo@2x.png ├── Base.lproj │ └── LaunchScreen.storyboard ├── Classes │ ├── Controller │ │ ├── AvatarPickerConfigurationViewController.swift │ │ ├── CustomPickerCellViewController.swift │ │ ├── EditorConfigurationViewController.swift │ │ ├── HomeViewController.swift │ │ ├── PhotoBrowserViewController.swift │ │ ├── PickerColorConfigurationViewController.swift │ │ ├── PickerConfigurationViewController.swift │ │ ├── PickerResultViewController.swift │ │ ├── PickerResultViewController.xib │ │ ├── TestEditorViewController.swift │ │ ├── WeChatMometViewController.swift │ │ ├── WeChatViewController.swift │ │ └── WindowPickerViewController.swift │ ├── Extension │ │ ├── Core+UIColor.swift │ │ ├── Extension.swift │ │ ├── RowTypeRule.swift │ │ ├── String+Extension.swift │ │ ├── UIDevice+Extension.swift │ │ ├── UIFont+Extension.swift │ │ └── UIImage+Extension.swift │ ├── Model │ │ ├── GPUImageBeautifyFilter.h │ │ ├── GPUImageBeautifyFilter.m │ │ ├── ImageFilter.swift │ │ └── Tools.swift │ └── View │ │ ├── ConfigurationViewCell.swift │ │ └── CustomPickerCellView.swift ├── HXPHPickerExample-Bridging-Header.h ├── Images │ ├── hx_sticker_chongya.png │ ├── hx_sticker_haoxinqing.png │ ├── hx_sticker_housailei.png │ ├── hx_sticker_jintianfenkeai.png │ ├── hx_sticker_keaibiaoq.png │ ├── hx_sticker_kehaixing.png │ ├── hx_sticker_saihong.png │ ├── hx_sticker_wow.png │ ├── hx_sticker_woxiangfazipai.png │ ├── hx_sticker_xiaochuzhujiao.png │ ├── hx_sticker_yuanqimanman.png │ ├── hx_sticker_yuanqishaonv.png │ ├── hx_sticker_zaizaijia.png │ ├── livephoto_image.jpeg │ ├── love.png │ ├── love_text.png │ ├── portrait.png │ ├── qiy.png │ ├── stars.png │ └── text.png ├── Info.plist ├── Music │ ├── 世间美好与你环环相扣 │ └── 世间美好与你环环相扣.mp3 ├── Reachability.swift ├── Resources │ └── custom.lproj │ │ └── Localizable.strings └── ar.lproj │ └── LaunchScreen.strings ├── SwiftUI ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── ConfigView.swift ├── ContentView.swift ├── PhotoBrowser.swift ├── PhotoPickerView.swift ├── PhotoView.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json └── SwiftUIExampleApp.swift └── tmp.xcconfig /.codecov.yml: -------------------------------------------------------------------------------- 1 | comment: 2 | layout: header, changes, diff 3 | coverage: 4 | ignore: 5 | - HXPhotoPickerExample 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: Silencelove 2 | custom: [https://github.com/sponsors/SilenceLove] 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | .DS_Store 62 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: 2 | - trailing_whitespace 3 | - statement_position 4 | - identifier_name 5 | - force_cast 6 | - large_tuple 7 | - function_parameter_count 8 | - nesting 9 | - notification_center_detachment 10 | - type_body_length 11 | 12 | excluded: 13 | - Carthage 14 | - Pods 15 | - Package.swift 16 | - Package.swift 17 | - Swift 18 | 19 | function_body_length: 20 | warning: 130 21 | error: 150 22 | 23 | file_length: 24 | warning: 1200 25 | error: 1500 26 | 27 | cyclomatic_complexity: 40 28 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode12.2 3 | 4 | before_install: 5 | - gem install xcpretty 6 | 7 | script: 8 | - set -o pipefail 9 | - xcodebuild clean -workspace HXPhotoPickerExample.xcworkspace -scheme "HXPhotoPickerExample" -sdk iphonesimulator build | xcpretty 10 | 11 | after_success: 12 | - sleep 4 13 | - bash <(curl -s https://codecov.io/bash) 14 | -------------------------------------------------------------------------------- /HXPhotoPickerExample.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.device.audio-input 8 | 9 | com.apple.security.device.camera 10 | 11 | com.apple.security.network.client 12 | 13 | com.apple.security.personal-information.location 14 | 15 | com.apple.security.personal-information.photos-library 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /HXPhotoPickerExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HXPhotoPickerExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /HXPhotoPickerExample.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Latest 7 | PreviewsEnabled 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /HXPhotoPickerExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /HXPhotoPickerExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /HXPhotoPickerExample.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 LoveZYForever 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Objective-C/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // HXPhotoPickerExample 4 | // 5 | // Created by Silence on 17/2/8. 6 | // Copyright © 2017年 Silence. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-1024.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-40.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/camera_overturn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "camera_overturn@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/camera_overturn.imageset/camera_overturn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/camera_overturn.imageset/camera_overturn@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/hotweibo_back_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hotweibo_back_icon@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/hotweibo_back_icon.imageset/hotweibo_back_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/hotweibo_back_icon.imageset/hotweibo_back_icon@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/hx_photo_edit_trash_close.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hx_photo_edit_trash_close@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/hx_photo_edit_trash_close.imageset/hx_photo_edit_trash_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/hx_photo_edit_trash_close.imageset/hx_photo_edit_trash_close@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/hx_photo_edit_trash_open.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hx_photo_edit_trash_open@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/hx_photo_edit_trash_open.imageset/hx_photo_edit_trash_open@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/hx_photo_edit_trash_open.imageset/hx_photo_edit_trash_open@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/wx_bg_image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "wx_bg_image@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/wx_bg_image.imageset/wx_bg_image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/wx_bg_image.imageset/wx_bg_image@2x.png -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/wx_head_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "wx_head_icon@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Objective-C/Assets.xcassets/wx_head_icon.imageset/wx_head_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Assets.xcassets/wx_head_icon.imageset/wx_head_icon@2x.png -------------------------------------------------------------------------------- /Objective-C/Classes/OCPickerExampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCPickerExampleViewController.h 3 | // HXPhotoPickerExample 4 | // 5 | // Created by Silence on 2023/6/14. 6 | // Copyright © 2023 洪欣. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface OCPickerExampleViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Objective-C/Classes/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // HXPhotoPickerExample 4 | // 5 | // Created by Silence on 17/2/8. 6 | // Copyright © 2017年 Silence. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Objective-C/Classes/assets/IMG_0168.GIF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Classes/assets/IMG_0168.GIF -------------------------------------------------------------------------------- /Objective-C/Classes/assets/c81.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Objective-C/Classes/assets/c81.mp4 -------------------------------------------------------------------------------- /Objective-C/HXPhotoPickerExample-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | 6 | #import "GPUImageBeautifyFilter.h" 7 | -------------------------------------------------------------------------------- /Objective-C/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // HXPhotoPickerExample 4 | // 5 | // Created by Silence on 17/2/8. 6 | // Copyright © 2017年 Silence. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "HXPhotoPicker", 8 | platforms: [.iOS(.v10)], 9 | products: [ 10 | .library( 11 | name: "HXPhotoPicker", 12 | targets: ["HXPhotoPicker"]), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "HXPhotoPicker", 17 | resources: [ 18 | .process("Resources/HXPhotoPicker.bundle"), 19 | .copy("Resources/PrivacyInfo.xcprivacy") 20 | ], 21 | swiftSettings: [ 22 | .define("HXPICKER_ENABLE_SPM"), 23 | .define("HXPICKER_ENABLE_PICKER"), 24 | .define("HXPICKER_ENABLE_EDITOR"), 25 | .define("HXPICKER_ENABLE_CAMERA") 26 | ]), 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | platform:ios,'10.0' 3 | 4 | install! 'cocoapods', 5 | disable_input_output_paths: true, 6 | warn_for_unused_master_specs_repo: false 7 | 8 | use_frameworks! 9 | 10 | target "HXPhotoPickerExample" do 11 | pod 'HXPhotoPicker', :path => './' 12 | 13 | # pod 'HXPhotoPicker/Kingfisher', :path => './' 14 | # pod 'HXPhotoPicker/SDWebImage', :path => './' 15 | 16 | # pod 'SwiftLint' Run Script "${PODS_ROOT}/SwiftLint/swiftlint" 17 | # pod 'GDPerformanceView-Swift' 18 | # pod 'GPUImage' 19 | end 20 | 21 | target "SwiftUIExample" do 22 | # pod 'HXPhotoPicker', :path => './' 23 | end 24 | 25 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - HXPhotoPicker (5.0.2): 3 | - HXPhotoPicker/Default (= 5.0.2) 4 | - HXPhotoPicker/Camera (5.0.2): 5 | - HXPhotoPicker/Camera/Lite (= 5.0.2) 6 | - HXPhotoPicker/Camera/Location (= 5.0.2) 7 | - HXPhotoPicker/Camera/Lite (5.0.2): 8 | - HXPhotoPicker/Core 9 | - HXPhotoPicker/Camera/Location (5.0.2): 10 | - HXPhotoPicker/Camera/Lite 11 | - HXPhotoPicker/Core (5.0.2): 12 | - HXPhotoPicker/Resources 13 | - HXPhotoPicker/Default (5.0.2): 14 | - HXPhotoPicker/Camera 15 | - HXPhotoPicker/Editor 16 | - HXPhotoPicker/Picker 17 | - HXPhotoPicker/Editor (5.0.2): 18 | - HXPhotoPicker/EditorView 19 | - HXPhotoPicker/EditorView (5.0.2): 20 | - HXPhotoPicker/Core 21 | - HXPhotoPicker/Picker (5.0.2): 22 | - HXPhotoPicker/Core 23 | - HXPhotoPicker/Resources (5.0.2) 24 | 25 | DEPENDENCIES: 26 | - HXPhotoPicker (from `./`) 27 | 28 | EXTERNAL SOURCES: 29 | HXPhotoPicker: 30 | :path: "./" 31 | 32 | SPEC CHECKSUMS: 33 | HXPhotoPicker: 1ca6745433790101b1aa9817e2d5dfac8fc8a557 34 | 35 | PODFILE CHECKSUM: f4206234be7b147393e92e59d20fd9822f9a69d3 36 | 37 | COCOAPODS: 1.16.2 38 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - HXPhotoPicker (5.0.2): 3 | - HXPhotoPicker/Default (= 5.0.2) 4 | - HXPhotoPicker/Camera (5.0.2): 5 | - HXPhotoPicker/Camera/Lite (= 5.0.2) 6 | - HXPhotoPicker/Camera/Location (= 5.0.2) 7 | - HXPhotoPicker/Camera/Lite (5.0.2): 8 | - HXPhotoPicker/Core 9 | - HXPhotoPicker/Camera/Location (5.0.2): 10 | - HXPhotoPicker/Camera/Lite 11 | - HXPhotoPicker/Core (5.0.2): 12 | - HXPhotoPicker/Resources 13 | - HXPhotoPicker/Default (5.0.2): 14 | - HXPhotoPicker/Camera 15 | - HXPhotoPicker/Editor 16 | - HXPhotoPicker/Picker 17 | - HXPhotoPicker/Editor (5.0.2): 18 | - HXPhotoPicker/EditorView 19 | - HXPhotoPicker/EditorView (5.0.2): 20 | - HXPhotoPicker/Core 21 | - HXPhotoPicker/Picker (5.0.2): 22 | - HXPhotoPicker/Core 23 | - HXPhotoPicker/Resources (5.0.2) 24 | 25 | DEPENDENCIES: 26 | - HXPhotoPicker (from `./`) 27 | 28 | EXTERNAL SOURCES: 29 | HXPhotoPicker: 30 | :path: "./" 31 | 32 | SPEC CHECKSUMS: 33 | HXPhotoPicker: 1ca6745433790101b1aa9817e2d5dfac8fc8a557 34 | 35 | PODFILE CHECKSUM: f4206234be7b147393e92e59d20fd9822f9a69d3 36 | 37 | COCOAPODS: 1.16.2 38 | -------------------------------------------------------------------------------- /Pods/Target Support Files/HXPhotoPicker/HXPhotoPicker-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_DEVELOPMENT_LANGUAGE} 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 5.0.2 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/HXPhotoPicker/HXPhotoPicker-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_HXPhotoPicker : NSObject 3 | @end 4 | @implementation PodsDummy_HXPhotoPicker 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/HXPhotoPicker/HXPhotoPicker-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/HXPhotoPicker/HXPhotoPicker-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double HXPhotoPickerVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char HXPhotoPickerVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/HXPhotoPicker/HXPhotoPicker.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/HXPhotoPicker 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_LDFLAGS = $(inherited) -framework "Photos" -framework "PhotosUI" -framework "UIKit" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} 10 | PODS_ROOT = ${SRCROOT} 11 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 14 | SKIP_INSTALL = YES 15 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = HXPICKER_ENABLE_CAMERA HXPICKER_ENABLE_CAMERA_LOCATION HXPICKER_ENABLE_CORE HXPICKER_ENABLE_EDITOR HXPICKER_ENABLE_EDITOR_VIEW HXPICKER_ENABLE_PICKER 16 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/HXPhotoPicker/HXPhotoPicker.modulemap: -------------------------------------------------------------------------------- 1 | framework module HXPhotoPicker { 2 | umbrella header "HXPhotoPicker-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/HXPhotoPicker/HXPhotoPicker.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/HXPhotoPicker 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_LDFLAGS = $(inherited) -framework "Photos" -framework "PhotosUI" -framework "UIKit" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} 10 | PODS_ROOT = ${SRCROOT} 11 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 14 | SKIP_INSTALL = YES 15 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = HXPICKER_ENABLE_CAMERA HXPICKER_ENABLE_CAMERA_LOCATION HXPICKER_ENABLE_CORE HXPICKER_ENABLE_EDITOR HXPICKER_ENABLE_EDITOR_VIEW HXPICKER_ENABLE_PICKER 16 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/HXPhotoPicker/ResourceBundle-HXPhotoPicker_Privacy-HXPhotoPicker-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_DEVELOPMENT_LANGUAGE} 7 | CFBundleIdentifier 8 | ${PRODUCT_BUNDLE_IDENTIFIER} 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | ${PRODUCT_NAME} 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 5.0.2 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-HXPhotoPickerExample/Pods-HXPhotoPickerExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_DEVELOPMENT_LANGUAGE} 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-HXPhotoPickerExample/Pods-HXPhotoPickerExample-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## HXPhotoPicker 5 | 6 | MIT License 7 | 8 | Copyright (c) 2017 LoveZYForever 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-HXPhotoPickerExample/Pods-HXPhotoPickerExample-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_HXPhotoPickerExample : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_HXPhotoPickerExample 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-HXPhotoPickerExample/Pods-HXPhotoPickerExample-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_HXPhotoPickerExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_HXPhotoPickerExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-HXPhotoPickerExample/Pods-HXPhotoPickerExample.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/HXPhotoPicker" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/HXPhotoPicker/HXPhotoPicker.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "HXPhotoPicker" -framework "Photos" -framework "PhotosUI" -framework "UIKit" 9 | OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/HXPhotoPicker" 10 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 11 | PODS_BUILD_DIR = ${BUILD_DIR} 12 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 13 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 14 | PODS_ROOT = ${SRCROOT}/Pods 15 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 16 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-HXPhotoPickerExample/Pods-HXPhotoPickerExample.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_HXPhotoPickerExample { 2 | umbrella header "Pods-HXPhotoPickerExample-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-HXPhotoPickerExample/Pods-HXPhotoPickerExample.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/HXPhotoPicker" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/HXPhotoPicker/HXPhotoPicker.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "HXPhotoPicker" -framework "Photos" -framework "PhotosUI" -framework "UIKit" 9 | OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/HXPhotoPicker" 10 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 11 | PODS_BUILD_DIR = ${BUILD_DIR} 12 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 13 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 14 | PODS_ROOT = ${SRCROOT}/Pods 15 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 16 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftUIExample/Pods-SwiftUIExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_DEVELOPMENT_LANGUAGE} 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftUIExample/Pods-SwiftUIExample-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftUIExample/Pods-SwiftUIExample-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftUIExample/Pods-SwiftUIExample-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SwiftUIExample : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SwiftUIExample 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftUIExample/Pods-SwiftUIExample-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_SwiftUIExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_SwiftUIExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftUIExample/Pods-SwiftUIExample.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 6 | PODS_ROOT = ${SRCROOT}/Pods 7 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 8 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftUIExample/Pods-SwiftUIExample.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_SwiftUIExample { 2 | umbrella header "Pods-SwiftUIExample-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SwiftUIExample/Pods-SwiftUIExample.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 6 | PODS_ROOT = ${SRCROOT}/Pods 7 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 8 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 9 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Camera+Location/CameraViewController+Location.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CameraViewController+Location.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/9/1. 6 | // 7 | 8 | #if HXPICKER_ENABLE_CAMERA_LOCATION && !targetEnvironment(macCatalyst) 9 | import UIKit 10 | import CoreLocation 11 | 12 | extension CameraViewController: CLLocationManagerDelegate { 13 | 14 | var allowLocation: Bool { 15 | let whenIn = Bundle.main.object(forInfoDictionaryKey: "NSLocationWhenInUseUsageDescription") != nil 16 | let always = Bundle.main.object(forInfoDictionaryKey: "NSLocationAlwaysUsageDescription") != nil 17 | return config.allowLocation && (whenIn || always) 18 | } 19 | 20 | func startLocation() { 21 | if !allowLocation { return } 22 | if CLLocationManager.authorizationStatus() != .denied { 23 | locationManager.startUpdatingLocation() 24 | didLocation = true 25 | } 26 | } 27 | 28 | public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 29 | if !locations.isEmpty { 30 | currentLocation = locations.last 31 | } 32 | } 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Camera/View/PassThrough.metal: -------------------------------------------------------------------------------- 1 | /* 2 | See LICENSE folder for this sample’s licensing information. 3 | 4 | Abstract: 5 | Pass-through shader (used for preview). 6 | */ 7 | 8 | #include 9 | using namespace metal; 10 | 11 | // Vertex input/output structure for passing results from vertex shader to fragment shader 12 | struct VertexIO 13 | { 14 | float4 position [[position]]; 15 | float2 textureCoord [[user(texturecoord)]]; 16 | }; 17 | 18 | // Vertex shader for a textured quad 19 | vertex VertexIO vertexPassThrough(const device packed_float4 *pPosition [[ buffer(0) ]], 20 | const device packed_float2 *pTexCoords [[ buffer(1) ]], 21 | uint vid [[ vertex_id ]]) 22 | { 23 | VertexIO outVertex; 24 | 25 | outVertex.position = pPosition[vid]; 26 | outVertex.textureCoord = pTexCoords[vid]; 27 | 28 | return outVertex; 29 | } 30 | 31 | // Fragment shader for a textured quad 32 | fragment half4 fragmentPassThrough(VertexIO inputFragment [[ stage_in ]], 33 | texture2d inputTexture [[ texture(0) ]], 34 | sampler samplr [[ sampler(0) ]]) 35 | { 36 | return inputTexture.sample(samplr, inputFragment.textureCoord); 37 | } 38 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Config/ImageViewConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageViewConfig.swift 3 | // HXPhotoPickerExample 4 | // 5 | // Created by Silence on 2025/2/21. 6 | // Copyright © 2025 Silence. All rights reserved. 7 | // 8 | 9 | 10 | import Foundation 11 | 12 | public protocol ImageViewConfig { 13 | var imageViewProtocol: HXImageViewProtocol.Type { get set } 14 | static var imageViewProtocol: HXImageViewProtocol.Type { get set } 15 | } 16 | 17 | public extension ImageViewConfig { 18 | var imageViewProtocol: HXImageViewProtocol.Type { 19 | get { PhotoManager.ImageView } 20 | set { PhotoManager.ImageView = newValue } 21 | } 22 | static var imageViewProtocol: HXImageViewProtocol.Type { 23 | get { PhotoManager.ImageView } 24 | set { PhotoManager.ImageView = newValue } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Config/PhotoDebugLogsConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoDebugLogsConfig.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/21. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol PhotoDebugLogsConfig { 12 | var isDebugLogsEnabled: Bool { get set } 13 | } 14 | 15 | public extension PhotoDebugLogsConfig { 16 | var isDebugLogsEnabled: Bool { 17 | get { PhotoManager.shared.isDebugLogsEnabled } 18 | set { PhotoManager.shared.isDebugLogsEnabled = newValue } 19 | } 20 | } 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Config/PhotoHUDConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoHUDConfig.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2024/4/3. 6 | // Copyright © 2024 Silence. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol PhotoHUDConfig { 12 | var hudView: PhotoHUDProtocol.Type { get set } 13 | } 14 | 15 | public extension PhotoHUDConfig { 16 | var hudView: PhotoHUDProtocol.Type { 17 | get { PhotoManager.HUDView } 18 | set { PhotoManager.HUDView = newValue } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+Bundle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+Bundle.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2020/11/15. 6 | // Copyright © 2020 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension Bundle { 12 | 13 | static func localizedString(for key: String) -> String { 14 | return localizedString(for: key, value: nil) 15 | } 16 | 17 | static func localizedString(for key: String, value: String?) -> String { 18 | let bundle = PhotoManager.shared.languageBundle 19 | guard let newValue = bundle?.localizedString(forKey: key, value: value, table: nil) else { 20 | return key 21 | } 22 | return newValue 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+CALayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+CALayer.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/7/14. 6 | // 7 | 8 | import UIKit 9 | 10 | extension CALayer { 11 | func convertedToImage( 12 | size: CGSize = .zero, 13 | scale: CGFloat? = nil 14 | ) -> UIImage? { 15 | var toSize: CGSize 16 | if size.equalTo(.zero) { 17 | toSize = frame.size 18 | }else { 19 | toSize = size 20 | } 21 | var _scale: CGFloat = 1 22 | if let scale = scale { 23 | _scale = scale 24 | }else { 25 | if !Thread.isMainThread { 26 | DispatchQueue.main.sync { 27 | _scale = UIScreen._scale 28 | } 29 | }else { 30 | _scale = UIScreen._scale 31 | } 32 | } 33 | let format = UIGraphicsImageRendererFormat() 34 | format.opaque = false 35 | format.scale = _scale 36 | let renderer = UIGraphicsImageRenderer(size: toSize, format: format) 37 | let image = renderer.image { context in 38 | render(in: context.cgContext) 39 | } 40 | return image 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+CGFloat.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+CGFloat.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2023/1/31. 6 | // 7 | 8 | import Foundation 9 | 10 | extension CGFloat { 11 | 12 | static var max: CGFloat { 13 | CGFloat(MAXFLOAT) 14 | } 15 | 16 | var compressionQuality: CGFloat { 17 | if self > 30000000 { 18 | return 30000000 / self 19 | }else if self > 15000000 { 20 | return 10000000 / self 21 | }else if self > 10000000 { 22 | return 6000000 / self 23 | }else { 24 | return 3000000 / self 25 | } 26 | } 27 | 28 | var transitionCompressionQuality: CGFloat { 29 | if self > 6000000 { 30 | return 3000000 / self 31 | }else if self > 3000000 { 32 | return 1000000 / self 33 | }else if self > 1000000 { 34 | return 600000 / self 35 | }else { 36 | return 1000000 / self 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+Data.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+Data.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/5/20. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Data { 11 | 12 | var imageContentType: ImageContentType { 13 | var values = [UInt8](repeating: 0, count: 1) 14 | copyBytes(to: &values, count: 1) 15 | switch values[0] { 16 | case 0xFF: 17 | return .jpg 18 | case 0x89: 19 | return .png 20 | case 0x47, 0x49, 0x46: 21 | return .gif 22 | default: 23 | return .unknown 24 | } 25 | } 26 | 27 | var isGif: Bool { 28 | imageContentType == .gif 29 | } 30 | 31 | var fileType: FileType { 32 | guard let firstByte = first else { 33 | return .unknown 34 | } 35 | switch firstByte { 36 | case 0xFF: 37 | return .image 38 | case 0x25: 39 | return .auido 40 | case 0x00: 41 | return .video 42 | default: 43 | return .unknown 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+Dictionary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+Dictionary.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/1/7. 6 | // 7 | 8 | import Photos 9 | 10 | extension Dictionary { 11 | 12 | /// 资源是否存在iCloud上 13 | var inICloud: Bool { 14 | if let isICloud = self[AnyHashable(PHImageResultIsInCloudKey) as! Key] as? Int { 15 | return isICloud == 1 16 | } 17 | return false 18 | } 19 | 20 | /// 资源是否取消了下载 21 | var isCancel: Bool { 22 | if let isCancel = self[AnyHashable(PHImageCancelledKey) as! Key] as? Int { 23 | return isCancel == 1 24 | } 25 | return false 26 | } 27 | var error: Error? { 28 | self[AnyHashable(PHImageErrorKey) as! Key] as? Error 29 | } 30 | /// 判断资源是否下载错误 31 | var isError: Bool { 32 | self[AnyHashable(PHImageErrorKey) as! Key] != nil 33 | } 34 | 35 | /// 判断资源下载得到的是否为退化的 36 | var isDegraded: Bool { 37 | if let isDegraded = self[AnyHashable(PHImageResultIsDegradedKey) as! Key] as? Int { 38 | return isDegraded == 1 39 | } 40 | return false 41 | } 42 | 43 | /// 判断资源是否下载完成 44 | var downloadFinined: Bool { 45 | !isCancel && !isError && !isDegraded 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+FileManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+FileManager.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2022/10/1. 6 | // 7 | 8 | import Foundation 9 | 10 | extension FileManager { 11 | class var documentPath: String { 12 | guard let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last else { 13 | return "" 14 | } 15 | return documentPath 16 | } 17 | class var cachesPath: String { 18 | guard let cachesPath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).last else { 19 | return "" 20 | } 21 | return cachesPath 22 | } 23 | class var tempPath: String { 24 | NSTemporaryDirectory() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+NSObject.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+NSObject.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/9. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension NSObject { 12 | 13 | static var className: String { 14 | String(describing: self) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+UICollectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+UICollectionView.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/9. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UICollectionView { 12 | func dequeueReusableCell(for indexPath: IndexPath) -> T { 13 | dequeueReusableCell(withReuseIdentifier: T.className, for: indexPath) as! T 14 | } 15 | 16 | func dequeueReusableCell(with cellClass: UICollectionViewCell.Type, for indexPath: IndexPath) -> UICollectionViewCell { 17 | dequeueReusableCell(withReuseIdentifier: cellClass.className, for: indexPath) 18 | } 19 | 20 | func register(_ cellClass: UICollectionViewCell.Type) { 21 | register(cellClass, forCellWithReuseIdentifier: cellClass.className) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+UIImageView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+UIImageView.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/1/9. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIImageView { 11 | 12 | func setImage(_ image: UIImage?, duration: CFTimeInterval = 0.2, animated: Bool = true) { 13 | if let image = image { 14 | if animated { 15 | UIView.transition( 16 | with: self, 17 | duration: duration, 18 | options: [.transitionCrossDissolve, .curveEaseInOut, .allowUserInteraction] 19 | ) { 20 | self.image = image 21 | } 22 | }else { 23 | self.image = image 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+UILabel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+UILabel.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/10/22. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UILabel { 11 | var textHeight: CGFloat { 12 | if let textHeight = text?.height(ofFont: font, maxWidth: width > 0 ? width : .max) { 13 | return textHeight 14 | } 15 | return 0 16 | } 17 | var textWidth: CGFloat { 18 | if let textWidth = text?.width(ofFont: font, maxHeight: height > 0 ? height : .max) { 19 | return textWidth 20 | } 21 | return 0 22 | } 23 | var textSize: CGSize { 24 | if let textSize = text?.size(ofFont: font, maxWidth: .max, maxHeight: .max) { 25 | return textSize 26 | } 27 | return .zero 28 | } 29 | } 30 | 31 | extension UILabel { 32 | /// 文本对齐方向 33 | var hxpicker_alignment: NSTextAlignment { 34 | set { 35 | switch newValue { 36 | case .left: 37 | textAlignment = PhotoManager.isRTL ? .right : .left 38 | case .right: 39 | textAlignment = PhotoManager.isRTL ? .left : .right 40 | default: 41 | textAlignment = newValue 42 | } 43 | } 44 | 45 | get { 46 | switch textAlignment { 47 | case .left: 48 | return PhotoManager.isRTL ? .right : textAlignment 49 | case .right: 50 | return PhotoManager.isRTL ? .left : textAlignment 51 | default: 52 | return textAlignment 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+UITableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+UITableView.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/9. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UITableView { 12 | 13 | func dequeueReusableCell() -> T { 14 | dequeueReusableCell(withIdentifier: T.className) as! T 15 | } 16 | 17 | func register(_ cellClass: UITableViewCell.Type) { 18 | register(cellClass, forCellReuseIdentifier: cellClass.className) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+UIViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+UIViewController.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/8/16. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIViewController { 11 | 12 | class var topViewController: UIViewController? { 13 | let window = UIApplication._keyWindow 14 | if var topViewController = window?.rootViewController { 15 | while true { 16 | if let controller = topViewController.presentedViewController { 17 | topViewController = controller 18 | }else if let navController = topViewController as? UINavigationController, 19 | let controller = navController.topViewController { 20 | topViewController = controller 21 | }else if let tabbarController = topViewController as? UITabBarController, 22 | let controller = tabbarController.selectedViewController { 23 | topViewController = controller 24 | }else { 25 | break 26 | } 27 | } 28 | return topViewController 29 | } 30 | return nil 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Extension/Core+URL.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+URL.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/6/17. 6 | // 7 | 8 | import Foundation 9 | 10 | extension URL { 11 | var isGif: Bool { 12 | absoluteString.hasSuffix("gif") || absoluteString.hasSuffix("GIF") 13 | } 14 | var fileSize: Int { 15 | guard let fileSize = try? resourceValues(forKeys: [.fileSizeKey]).fileSize else { 16 | return 0 17 | } 18 | return fileSize 19 | } 20 | 21 | var fileType: FileType { 22 | guard let fileData = try? Data(contentsOf: self) else { 23 | return .unknown 24 | } 25 | return fileData.fileType 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Model/AppearanceStyle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppearanceStyle.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/1/7. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum AppearanceStyle: Int { 11 | /// 跟随系统变化 12 | case varied = 0 13 | /// 正常风格,不会跟随系统变化 14 | case normal = 1 15 | /// 暗黑风格 16 | case dark = 2 17 | } 18 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Model/CustomLanguage.swift: -------------------------------------------------------------------------------- 1 | // CustomLanguage.swift 2 | // HXPhotoPicker 3 | // 4 | // Created by Slience on 2021/1/7. 5 | // Created by Silence on 2024/3/30. 6 | // Copyright © 2024 Silence. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public class CustomLanguage { 12 | 13 | /// 会与 Locale.preferredLanguages 进行匹配,匹配成功的才会使用。请确保正确性 14 | public let language: String 15 | /// 语言Bundle 16 | /// ``` 17 | /// - xxx.lproj 18 | /// - Localizable.strings 19 | /// ``` 20 | public let bundle: Bundle 21 | 22 | public init( 23 | language: String, 24 | bundle: Bundle 25 | ) { 26 | self.language = language 27 | self.bundle = bundle 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Model/ExportPreset.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExportPreset.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/8/18. 6 | // 7 | 8 | import UIKit 9 | import AVFoundation 10 | 11 | public struct VideoExportParameter { 12 | /// 视频导出的分辨率 13 | public let preset: ExportPreset 14 | /// 视频质量 [1 - 10] 15 | public let quality: Int 16 | 17 | /// 设置视频导出参数 18 | /// - Parameters: 19 | /// - exportPreset: 视频导出的分辨率 20 | /// - videoQuality: 视频质量 [1 - 10] 21 | public init( 22 | preset: ExportPreset, 23 | quality: Int 24 | ) { 25 | self.preset = preset 26 | self.quality = quality 27 | } 28 | } 29 | 30 | public enum ExportPreset { 31 | case lowQuality 32 | case mediumQuality 33 | case highQuality 34 | case ratio_640x480 35 | case ratio_960x540 36 | case ratio_1280x720 37 | 38 | public var name: String { 39 | switch self { 40 | case .lowQuality: 41 | return AVAssetExportPresetLowQuality 42 | case .mediumQuality: 43 | return AVAssetExportPresetMediumQuality 44 | case .highQuality: 45 | return AVAssetExportPresetHighestQuality 46 | case .ratio_640x480: 47 | return AVAssetExportPreset640x480 48 | case .ratio_960x540: 49 | return AVAssetExportPreset960x540 50 | case .ratio_1280x720: 51 | return AVAssetExportPreset1280x720 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Model/HXLog.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HXLog.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/21. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | 10 | internal func HXLog( 11 | _ description: String, 12 | fileName: String = #file, 13 | lineNumber: Int = #line, 14 | functionName: String = #function 15 | ) { 16 | if !PhotoManager.shared.isDebugLogsEnabled { 17 | return 18 | } 19 | // swiftlint:disable:next line_length 20 | let traceString = "🖼 PhotoPicker. \(fileName.components(separatedBy: "/").last!) -> \(functionName) -> \(description) (line: \(lineNumber))" 21 | print(traceString) 22 | } 23 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Model/ImageContentType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageContentType.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/5/21. 6 | // 7 | 8 | import UIKit 9 | 10 | public enum ImageContentType: String { 11 | case jpg, png, gif, unknown 12 | public var fileExtension: String { 13 | return self.rawValue 14 | } 15 | } 16 | 17 | enum FileType: String { 18 | case unknown 19 | case image 20 | case auido 21 | case video 22 | } 23 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Model/IndicatorType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndicatorType.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/1/8. 6 | // 7 | 8 | import UIKit 9 | 10 | public enum IndicatorType { 11 | /// gradient ring 12 | /// 渐变圆环 13 | case circle 14 | 15 | case circleJoin 16 | 17 | /// System chrysanthemum 18 | /// 系统菊花 19 | case system 20 | } 21 | 22 | public protocol IndicatorTypeConfig { 23 | /// Loading indicator type 24 | /// 加载指示器类型 25 | var indicatorType: IndicatorType { get set } 26 | } 27 | 28 | public extension IndicatorTypeConfig { 29 | var indicatorType: IndicatorType { 30 | get { PhotoManager.shared.indicatorType } 31 | set { PhotoManager.shared.indicatorType = newValue } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Model/LanguageType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LanguageType.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/1/7. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum LanguageType: Equatable { 11 | /// 跟随系统语言 12 | case system 13 | /// 中文简体 14 | case simplifiedChinese 15 | /// 中文繁体 16 | case traditionalChinese 17 | /// 日文 18 | case japanese 19 | /// 韩文 20 | case korean 21 | /// 英文 22 | case english 23 | /// 泰语 24 | case thai 25 | /// 印尼语 26 | case indonesia 27 | /// 越南语 28 | case vietnamese 29 | /// 俄语 30 | case russian 31 | /// 德语 32 | case german 33 | /// 法语 34 | case french 35 | /// 阿拉伯 36 | case arabic 37 | /// 西班牙 38 | case spanish 39 | /// 葡萄牙 40 | case portuguese 41 | 42 | case custom(Bundle) 43 | } 44 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/Model/PhotoPanGestureRecognizer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPanGestureRecognizer.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/7/1. 6 | // 7 | 8 | import UIKit 9 | 10 | class PhotoPanGestureRecognizer: UIPanGestureRecognizer { 11 | override func touchesBegan(_ touches: Set, with event: UIEvent) { 12 | super.touchesBegan(touches, with: event) 13 | state = .began 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Core/View/VideoPlayer/VideoPlayerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoPlayerView.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/1/9. 6 | // 7 | 8 | import UIKit 9 | import AVFoundation 10 | 11 | class VideoPlayerView: UIView { 12 | 13 | override class var layerClass: AnyClass { 14 | return AVPlayerLayer.self 15 | } 16 | 17 | var player: AVPlayer! 18 | 19 | var playerLayer: AVPlayerLayer { 20 | return layer as! AVPlayerLayer 21 | } 22 | 23 | var avAsset: AVAsset? 24 | 25 | init() { 26 | player = AVPlayer() 27 | super.init(frame: .zero) 28 | } 29 | 30 | required init?(coder: NSCoder) { 31 | fatalError("init(coder:) has not been implemented") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor+View/Extension/EditorView+AVAsset.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorView+AVAsset.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2023/2/25. 6 | // 7 | 8 | import UIKit 9 | import AVFoundation 10 | 11 | extension AVAsset { 12 | 13 | var videoOrientation: EditorVideoOrientation { 14 | guard let videoTrack = tracks(withMediaType: .video).first else { 15 | return .landscapeRight 16 | } 17 | 18 | let t = videoTrack.preferredTransform 19 | 20 | if (t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0) || 21 | (t.a == 0 && t.b == 1.0 && t.c == 1.0 && t.d == 0) { 22 | return .portrait // 90 23 | } else if (t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0) || 24 | (t.a == 0 && t.b == -1.0 && t.c == -1.0 && t.d == 0) { 25 | return .portraitUpsideDown // 270 26 | } else if t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0 { 27 | return .landscapeRight // 0 28 | } else if t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0 { 29 | return .landscapeLeft // 180 30 | } else { 31 | return .landscapeRight 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor+View/Extension/EditorView+CGFloat.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CGFloat+EditorView.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2023/1/19. 6 | // 7 | 8 | import Foundation 9 | 10 | extension CGFloat { 11 | var angle: CGFloat { 12 | self * (180 / .pi) 13 | } 14 | var radians: CGFloat { 15 | self / 180 * .pi 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor+View/VideoEditedResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoEditedResult.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/5/26. 6 | // 7 | 8 | import UIKit 9 | 10 | public struct VideoEditedResult { 11 | 12 | /// Edited video url 13 | /// 编辑后的视频地址 14 | public var url: URL { 15 | urlConfig.url 16 | } 17 | 18 | public let urlConfig: EditorURLConfig 19 | 20 | /// Edited video cover 21 | /// 编辑后的视频封面 22 | public let coverImage: UIImage? 23 | 24 | /// Edited video size 25 | /// 编辑后的视频大小 26 | public let fileSize: Int 27 | 28 | /// Video duration format: 00:00 29 | /// 视频时长 格式:00:00 30 | public let videoTime: String 31 | 32 | /// 视频时长 秒 33 | public let videoDuration: TimeInterval 34 | 35 | /// Edit the state of the view 36 | /// 编辑视图的状态 37 | public let data: EditAdjustmentData? 38 | 39 | public init(data: EditAdjustmentData? = nil) { 40 | self.data = data 41 | urlConfig = .empty 42 | coverImage = nil 43 | fileSize = 0 44 | videoTime = "00:00" 45 | videoDuration = 0 46 | } 47 | 48 | init( 49 | urlConfig: EditorURLConfig, 50 | coverImage: UIImage?, 51 | fileSize: Int, 52 | videoTime: String, 53 | videoDuration: TimeInterval, 54 | data: EditAdjustmentData? 55 | ) { 56 | self.urlConfig = urlConfig 57 | self.coverImage = coverImage 58 | self.fileSize = fileSize 59 | self.videoTime = videoTime 60 | self.videoDuration = videoDuration 61 | self.data = data 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor+View/View/EditorFrameView+Control.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorFrameView+Control.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2022/11/13. 6 | // 7 | 8 | import UIKit 9 | 10 | extension EditorFrameView: EditorControlViewDelegate { 11 | func controlView(beganChanged controlView: EditorControlView, _ rect: CGRect) { 12 | if !controlView.isUserInteractionEnabled { 13 | return 14 | } 15 | hideMaskBgView() 16 | maskLinesView.hideGridGraylinesView(animated: true) 17 | stopControlTimer() 18 | delegate?.frameView(beganChanged: self, rect) 19 | hideVideoSilder(true) 20 | } 21 | 22 | func controlView(didChanged controlView: EditorControlView, _ rect: CGRect) { 23 | if !controlView.isUserInteractionEnabled { 24 | return 25 | } 26 | stopControlTimer() 27 | maskBgView.updateLayers(rect, false) 28 | customMaskView.updateLayers(rect, false) 29 | maskLinesView.updateLayers(rect, false) 30 | updateVideoSlider(to: rect, animated: false) 31 | delegate?.frameView(didChanged: self, rect) 32 | } 33 | 34 | func controlView(endChanged controlView: EditorControlView, _ rect: CGRect) { 35 | if !controlView.isUserInteractionEnabled { 36 | return 37 | } 38 | startControlTimer() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor+View/View/EditorFrameView+VideoPlay.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorFrameView+VideoPlay.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/5/4. 6 | // 7 | 8 | import UIKit 9 | 10 | extension EditorFrameView: VideoPlaySliderViewDelegate { 11 | 12 | func videoSliderView( 13 | _ videoSliderView: VideoPlaySliderView, 14 | didChangedPlayDuration duration: CGFloat, 15 | state: VideoControlEvent 16 | ) { 17 | delegate?.frameView(self, didChangedPlayTime: duration, for: state) 18 | } 19 | 20 | func videoSliderView( 21 | _ videoSliderView: VideoPlaySliderView, 22 | didPlayButtonClick isSelected: Bool 23 | ) { 24 | delegate?.frameView(self, didPlayButtonClick: isSelected) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor+View/View/EditorView+GestureRecognizer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorView+GestureRecognizer.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2022/11/13. 6 | // 7 | 8 | import UIKit 9 | 10 | extension EditorView: UIGestureRecognizerDelegate { 11 | 12 | public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { 13 | if gestureRecognizer is UIPanGestureRecognizer { 14 | if isDrawEnabled || isMosaicEnabled { 15 | return false 16 | } 17 | } 18 | return true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor+View/View/EditorView+ScrollView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorView+ScrollView.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2022/11/13. 6 | // 7 | 8 | import UIKit 9 | 10 | extension EditorView: UIScrollViewDelegate { 11 | 12 | public func viewForZooming(in scrollView: UIScrollView) -> UIView? { 13 | (allowZoom && isCanZoomScale) ? adjusterView : nil 14 | } 15 | public func scrollViewDidZoom(_ scrollView: UIScrollView) { 16 | if !allowZoom || !isCanZoomScale { 17 | return 18 | } 19 | let viewWidth = scrollView.width - scrollView.contentInset.left - scrollView.contentInset.right 20 | let viewHeight = scrollView.height - scrollView.contentInset.top - scrollView.contentInset.bottom 21 | let offsetX = (viewWidth > scrollView.contentSize.width) ? 22 | (viewWidth - scrollView.contentSize.width) * 0.5 : 0 23 | let offsetY = (viewHeight > scrollView.contentSize.height) ? 24 | (viewHeight - scrollView.contentSize.height) * 0.5 : 0 25 | let centerX = scrollView.contentSize.width * 0.5 + offsetX 26 | let centerY = scrollView.contentSize.height * 0.5 + offsetY 27 | adjusterView.center = CGPoint(x: centerX, y: centerY) 28 | } 29 | public func scrollViewDidEndZooming( 30 | _ scrollView: UIScrollView, 31 | with view: UIView?, 32 | atScale scale: CGFloat 33 | ) { 34 | adjusterView.zoomScale = scale 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/Controller/EditorViewController+Mosaic.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorViewController+Mosaic.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/5/20. 6 | // 7 | 8 | import UIKit 9 | 10 | extension EditorViewController: EditorMosaicToolViewDelegate { 11 | func mosaicToolView(_ mosaicToolView: EditorMosaicToolView, didChangedMosaicType type: EditorMosaicType) { 12 | editorView.mosaicType = type 13 | } 14 | 15 | func mosaicToolView(didUndoClick mosaicToolView: EditorMosaicToolView) { 16 | editorView.undoMosaic() 17 | mosaicToolView.canUndo = editorView.isCanUndoMosaic 18 | checkFinishButtonState() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/Controller/EditorViewController+Text.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorViewController+Text.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/5/17. 6 | // 7 | 8 | import UIKit 9 | 10 | extension EditorViewController: EditorStickerTextViewControllerDelegate { 11 | func stickerTextViewController( 12 | _ controller: EditorStickerTextViewController, 13 | didFinish stickerText: EditorStickerText 14 | ) { 15 | deselectedDrawTool() 16 | if let tool = selectedTool, 17 | tool.type == .graffiti || tool.type == .graffiti { 18 | selectedTool = nil 19 | updateBottomMaskLayer() 20 | } 21 | editorView.addSticker(stickerText) 22 | checkSelectedTool() 23 | checkFinishButtonState() 24 | } 25 | 26 | func stickerTextViewController( 27 | _ controller: EditorStickerTextViewController, 28 | didFinishUpdate stickerText: EditorStickerText 29 | ) { 30 | deselectedDrawTool() 31 | if let tool = selectedTool, 32 | tool.type == .graffiti || tool.type == .graffiti { 33 | selectedTool = nil 34 | updateBottomMaskLayer() 35 | } 36 | editorView.updateSticker(stickerText) 37 | checkSelectedTool() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/Model/EditorChartlet.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorChartlet.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/7/26. 6 | // 7 | 8 | import UIKit 9 | 10 | public typealias EditorTitleChartletResponse = ([EditorChartlet]) -> Void 11 | public typealias EditorChartletListResponse = (Int, [EditorChartlet]) -> Void 12 | 13 | public struct EditorChartlet { 14 | 15 | /// 贴图对应的 UIImage 对象, 视频支持gif 16 | public let image: UIImage? 17 | 18 | public let imageData: Data? 19 | 20 | /// 贴图对应的 网络地址(视频支持gif) 21 | public let url: URL? 22 | 23 | public let ext: Any? 24 | 25 | public init( 26 | image: UIImage?, 27 | imageData: Data? = nil, 28 | ext: Any? = nil 29 | ) { 30 | self.image = image 31 | self.imageData = imageData 32 | self.ext = ext 33 | url = nil 34 | } 35 | 36 | public init( 37 | url: URL?, 38 | ext: Any? = nil 39 | ) { 40 | self.url = url 41 | self.ext = ext 42 | image = nil 43 | imageData = nil 44 | } 45 | } 46 | 47 | class EditorChartletTitle { 48 | 49 | /// 标题图标 对应的 UIImage 数据 50 | let image: UIImage? 51 | 52 | /// 标题图标 对应的 网络地址 53 | let url: URL? 54 | 55 | init(image: UIImage?) { 56 | self.image = image 57 | url = nil 58 | } 59 | 60 | init(url: URL?) { 61 | self.url = url 62 | image = nil 63 | } 64 | 65 | var isSelected = false 66 | var isLoading = false 67 | var isAlbum = false 68 | var chartletList: [EditorChartlet] = [] 69 | } 70 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/Protocol/EditorChartletListProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorChartletListProtocol.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/11/7. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum EditorChartletType { 12 | case image(UIImage) 13 | case data(Data) 14 | } 15 | 16 | public protocol EditorChartletListDelegate: AnyObject { 17 | func chartletList( 18 | _ chartletList: EditorChartletListProtocol, 19 | didSelectedWith type: EditorChartletType 20 | ) 21 | } 22 | 23 | public protocol EditorChartletListProtocol: UIViewController { 24 | var delegate: EditorChartletListDelegate? { get set } 25 | init(config: EditorConfiguration, editorType: EditorContentViewType) 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/Protocol/EditorMaskListProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorMaskListProtocol.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2024/3/16. 6 | // Copyright © 2024 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol EditorMaskListDelete: AnyObject { 12 | func editorMaskList( 13 | _ chartletList: EditorMaskListProtocol, 14 | didSelectedWith image: UIImage 15 | ) 16 | } 17 | 18 | public protocol EditorMaskListProtocol: UIViewController { 19 | var delegate: EditorMaskListDelete? { get set } 20 | init(config: EditorConfiguration) 21 | } 22 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/View/EditorCollectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorCollectionView.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/5/10. 6 | // 7 | 8 | import UIKit 9 | 10 | class EditorCollectionView: UICollectionView { 11 | public override func touchesShouldCancel(in view: UIView) -> Bool { 12 | true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/View/ExpandButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExpandButton.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/8. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ExpandButton: UIButton { 12 | override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 13 | bounds.insetBy(dx: -15, dy: -15).contains(point) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/View/Text/EditorStickerTextView+Delegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorStickerTextView+Delegate.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/8/25. 6 | // 7 | 8 | import UIKit 9 | 10 | extension EditorStickerTextView: UITextViewDelegate { 11 | func textViewDidChange(_ textView: UITextView) { 12 | textView.typingAttributes = typingAttributes 13 | if textIsDelete { 14 | drawTextBackgroudColor() 15 | textIsDelete = false 16 | } 17 | if !textView.text.isEmpty { 18 | if textView.text.count > config.maximumLimitTextLength && 19 | config.maximumLimitTextLength > 0 { 20 | let text = textView.text[.. Bool { 28 | if text.isEmpty { 29 | textIsDelete = true 30 | } 31 | return true 32 | } 33 | } 34 | 35 | extension EditorStickerTextView: NSLayoutManagerDelegate { 36 | func layoutManager( 37 | _ layoutManager: NSLayoutManager, 38 | didCompleteLayoutFor textContainer: NSTextContainer?, 39 | atEnd layoutFinishedFlag: Bool 40 | ) { 41 | if layoutFinishedFlag { 42 | drawTextBackgroudColor() 43 | } 44 | } 45 | } 46 | 47 | class EditorStickerTextLayer: CAShapeLayer { 48 | } 49 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/View/Video/EditorMusicLyricViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorMusicLyricViewCell.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/5/20. 6 | // 7 | 8 | import UIKit 9 | 10 | class EditorMusicLyricViewCell: UICollectionViewCell { 11 | 12 | var lyricLb: UILabel! 13 | 14 | var lyric: VideoEditorLyric! { 15 | didSet { 16 | lyricLb.text = lyric.lyric 17 | } 18 | } 19 | override init(frame: CGRect) { 20 | super.init(frame: frame) 21 | lyricLb = UILabel() 22 | lyricLb.font = .mediumPingFang(ofSize: 16) 23 | lyricLb.textColor = .white 24 | contentView.addSubview(lyricLb) 25 | } 26 | override func layoutSubviews() { 27 | super.layoutSubviews() 28 | lyricLb.frame = bounds 29 | } 30 | required init?(coder: NSCoder) { 31 | fatalError("init(coder:) has not been implemented") 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Editor/View/Video/EditorVideoControlViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditorVideoControlViewCell.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/5/13. 6 | // 7 | 8 | import UIKit 9 | 10 | class EditorVideoControlViewCell: UICollectionViewCell { 11 | 12 | private var imageView: UIImageView! 13 | 14 | var image: UIImage? { 15 | didSet { 16 | guard let image else { return } 17 | imageView.setImage(image, animated: true) 18 | } 19 | } 20 | 21 | override init(frame: CGRect) { 22 | super.init(frame: frame) 23 | imageView = UIImageView() 24 | imageView.clipsToBounds = true 25 | imageView.contentMode = .scaleAspectFill 26 | addSubview(imageView) 27 | } 28 | 29 | required init?(coder: NSCoder) { 30 | fatalError("init(coder:) has not been implemented") 31 | } 32 | 33 | override func layoutSubviews() { 34 | super.layoutSubviews() 35 | imageView.frame = bounds 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/AssetResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AssetResult.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/9/9. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public struct AssetResult { 12 | public let image: UIImage 13 | public var url: URL { urlReuslt.url } 14 | public let urlReuslt: AssetURLResult 15 | 16 | public init(image: UIImage, urlReuslt: AssetURLResult) { 17 | self.image = image 18 | self.urlReuslt = urlReuslt 19 | } 20 | } 21 | 22 | @available(iOS 13.0, *) 23 | extension AssetResult: PhotoAssetObject { 24 | 25 | public static func fetchObject( 26 | _ photoAsset: PhotoAsset, 27 | toFile fileConfig: PhotoAsset.FileConfig?, 28 | compression: PhotoAsset.Compression? 29 | ) async throws -> Self { 30 | try await withCheckedThrowingContinuation { continuation in 31 | photoAsset.getAssetResult(toFile: fileConfig, compression: compression) { 32 | switch $0 { 33 | case .success(let result): 34 | continuation.resume(with: .success(result)) 35 | case .failure(let error): 36 | continuation.resume(with: .failure(error)) 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Config/AlbumTitleViewConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumTitleViewConfiguration.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/8/30. 6 | // 7 | 8 | import UIKit 9 | 10 | // MARK: Album title view configuration class, valid when the pop-up window displays the album list / 相册标题视图配置类,弹窗展示相册列表时有效 11 | public struct AlbumTitleViewConfiguration { 12 | 13 | public var backgroundColor: UIColor? 14 | 15 | /// Background color in dark style 16 | /// 暗黑风格下背景颜色 17 | public var backgroudDarkColor: UIColor? 18 | 19 | /// Arrow configuration 20 | /// 箭头配置 21 | public var arrow: ArrowViewConfiguration = .init() 22 | 23 | public init() { } 24 | 25 | public mutating func setThemeColor(_ color: UIColor) { 26 | arrow.setThemeColor(color) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Config/ArrowViewConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArrowViewConfiguration.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/8/30. 6 | // 7 | 8 | import UIKit 9 | 10 | // MARK: Album title view configuration class, valid when the pop-up window displays the album list / 相册标题视图配置类,弹窗展示相册列表时有效 11 | public struct ArrowViewConfiguration { 12 | 13 | /// 箭头背景颜色 14 | public var backgroundColor: UIColor = .systemBlue 15 | 16 | /// 箭头颜色 17 | public var arrowColor: UIColor = "#ffffff".hx.color 18 | 19 | /// 暗黑风格下箭头背景颜色 20 | public var backgroudDarkColor: UIColor = .systemBlue 21 | 22 | /// 暗黑风格下箭头颜色 23 | public var arrowDarkColor: UIColor = "#ffffff".hx.color 24 | 25 | public init() { } 26 | 27 | public mutating func setThemeColor(_ color: UIColor) { 28 | backgroundColor = color 29 | backgroudDarkColor = color 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Config/EmptyViewConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EmptyViewConfiguration.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2020/12/29. 6 | // Copyright © 2020 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: 照片列表空资源时展示的视图 12 | public struct EmptyViewConfiguration { 13 | 14 | /// 标题颜色 15 | public var titleColor: UIColor = "#666666".hx.color 16 | 17 | /// 暗黑风格下标题颜色 18 | public var titleDarkColor: UIColor = "#ffffff".hx.color 19 | 20 | /// 子标题颜色 21 | public var subTitleColor: UIColor = "#999999".hx.color 22 | 23 | /// 暗黑风格下子标题颜色 24 | public var subTitleDarkColor: UIColor = "#dadada".hx.color 25 | 26 | public init() { } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Config/SystemCameraConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SystemCameraConfiguration.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2020/12/29. 6 | // Copyright © 2020 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import AVFoundation 11 | 12 | // MARK: System camera configuration class / 系统相机配置类 13 | public struct SystemCameraConfiguration { 14 | 15 | /// 媒体类型 16 | /// [kUTTypeImage, kUTTypeMovie] 17 | public var mediaTypes: [String] = [] 18 | 19 | /// Maximum video recording time 20 | /// 视频最大录制时长 21 | public var videoMaximumDuration: TimeInterval = 60 22 | 23 | /// Video quality at the time of shooting 24 | /// 拍摄时的视频质量 25 | public var videoQuality: UIImagePickerController.QualityType = .typeHigh 26 | 27 | /// Video Editing Crop Export Resolution 28 | /// 视频编辑裁剪导出的分辨率 29 | public var editExportPreset: ExportPreset = .ratio_960x540 30 | 31 | /// Video Editing Cropping Export Quality 32 | /// 视频编辑裁剪导出的质量 33 | public var editVideoQuality: Int = 6 34 | 35 | /// Use the rear camera by default 36 | /// 默认使用后置相机 37 | public var cameraDevice: UIImagePickerController.CameraDevice = .rear 38 | 39 | /// allow editing 40 | /// 允许编辑 41 | public var allowsEditing: Bool = true 42 | 43 | public init() { } 44 | } 45 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Extension/Picker+ConfigExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Picker+ConfigExtension.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/9/28. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension PickerConfiguration { 12 | 13 | var isSingleVideo: Bool { 14 | selectMode == .multiple && 15 | !allowSelectedTogether && 16 | maximumSelectedVideoCount == 1 && 17 | selectOptions.isPhoto && 18 | selectOptions.isVideo && 19 | photoList.cell.isHiddenSingleVideoSelect 20 | } 21 | 22 | var isMultipleSelect: Bool { 23 | selectMode == .multiple 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Extension/Picker+Int.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Picker+Int.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/5/5. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Int { 11 | 12 | var bytesString: String { 13 | let formatter = ByteCountFormatter() 14 | formatter.allowedUnits = [.useBytes, .useKB, .useMB] 15 | formatter.countStyle = .file 16 | return formatter.string(fromByteCount: Int64(self)) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Extension/Picker+PHAssetCollection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Picke+PHAssetCollection.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/1/7. 6 | // 7 | 8 | import UIKit 9 | import Photos 10 | 11 | extension PHAssetCollection { 12 | 13 | /// 是否相机胶卷 14 | var isCameraRoll: Bool { 15 | var versionStr = UIDevice.current.systemVersion.replacingOccurrences(of: ".", with: "") 16 | if versionStr.count <= 1 { 17 | versionStr.append("00") 18 | }else if versionStr.count <= 2 { 19 | versionStr.append("0") 20 | } 21 | let version: Int 22 | if let index = Int(versionStr) { 23 | version = index 24 | }else { 25 | version = 0 26 | } 27 | if version >= 800 && version <= 802 { 28 | return assetCollectionSubtype == .smartAlbumRecentlyAdded 29 | }else { 30 | return assetCollectionSubtype == .smartAlbumUserLibrary 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Model/LivePhotoError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LivePhotoError.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/1/7. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum LivePhotoError: Error { 11 | case imageError(AssetError) 12 | case videoError(AssetError) 13 | case allError(AssetError) 14 | 15 | var assetError: AssetError { 16 | switch self { 17 | case .imageError(let error): 18 | return error 19 | case .videoError(let error): 20 | return error 21 | case .allError(let error): 22 | return error 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Model/PhotoError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoError.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/1/7. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum PhotoError: LocalizedError { 11 | 12 | public enum `Type` { 13 | case imageEmpty 14 | case videoEmpty 15 | case exportFailed 16 | } 17 | case error(type: Type, message: String) 18 | } 19 | 20 | extension PhotoError { 21 | public var errorDescription: String? { 22 | switch self { 23 | case let .error(_, message): 24 | return message 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/PickerView/PhotoPickerSwitchLayout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerSwitchLayout.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/9/22. 6 | // 7 | 8 | import UIKit 9 | 10 | class PhotoPickerSwitchLayout: UICollectionViewFlowLayout { 11 | var changing: Bool = false 12 | override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { 13 | if changing { 14 | return CGPoint(x: -collectionView!.contentInset.left, y: -collectionView!.contentInset.top) 15 | } 16 | return super.targetContentOffset(forProposedContentOffset: proposedContentOffset) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/Transition/PhotoBrowserAnimationTransitioning.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoBrowserBrowserAnimationTransitioning.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2024/2/24. 6 | // Copyright © 2024 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum PhotoBrowserAnimationTransitionType { 12 | case present 13 | case dismiss 14 | } 15 | 16 | public protocol PhotoBrowserAnimationTransitioning: UIViewControllerAnimatedTransitioning { 17 | init(type: PhotoBrowserAnimationTransitionType) 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/Transition/PhotoBrowserInteractiveTransition.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoBrowserInteractiveTransition.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2024/2/25. 6 | // Copyright © 2024 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class PhotoBrowserInteractiveTransition: UIPercentDrivenInteractiveTransition { 12 | public weak var pickerController: PhotoPickerController? 13 | /// 是否可以手势返回 14 | public var canInteration: Bool = false 15 | 16 | public required init(pickerController: PhotoPickerController) { 17 | self.pickerController = pickerController 18 | super.init() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/Transition/PhotoPickerControllerAnimationTransitioning.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PickerAnimationTransitioning.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2024/2/24. 6 | // Copyright © 2024 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum PhotoPickerControllerTransitionType { 12 | case push 13 | case pop 14 | case dismiss 15 | } 16 | 17 | public protocol PhotoPickerControllerAnimationTransitioning: UIViewControllerAnimatedTransitioning { 18 | init(type: PhotoPickerControllerTransitionType) 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/Transition/PhotoPickerControllerInteractiveTransition.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerControllerInteractiveTransition.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2024/2/24. 6 | // Copyright © 2024 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class PhotoPickerControllerInteractiveTransition: UIPercentDrivenInteractiveTransition { 12 | 13 | public let type: InteractiveTransitionType 14 | public weak var pickerController: PhotoPickerController? 15 | /// 手势触发范围 16 | public let triggerRange: CGFloat 17 | /// 是否可以手势返回 18 | public var canInteration: Bool = false 19 | /// 返回手势 20 | open var gestureRecognizer: UIGestureRecognizer? { nil } 21 | 22 | public required init( 23 | type: InteractiveTransitionType, 24 | pickerController: PhotoPickerController, 25 | triggerRange: CGFloat 26 | ) { 27 | self.type = type 28 | self.pickerController = pickerController 29 | self.triggerRange = triggerRange 30 | super.init() 31 | } 32 | 33 | public enum InteractiveTransitionType { 34 | case pop 35 | case dismiss 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/AlbumList/PhotoAlbumController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoAlbumController.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/18. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol PhotoAlbumControllerDelegate: AnyObject { 12 | func albumController(_ albumController: PhotoAlbumController, didSelectedWith assetCollection: PhotoAssetCollection) 13 | func albumController(willAppear viewController: PhotoAlbumController) 14 | func albumController(didAppear viewController: PhotoAlbumController) 15 | func albumController(willDisappear viewController: PhotoAlbumController) 16 | func albumController(didDisappear viewController: PhotoAlbumController) 17 | } 18 | 19 | public protocol PhotoAlbumController: UIViewController { 20 | var delegate: PhotoAlbumControllerDelegate? { get set } 21 | var assetCollections: [PhotoAssetCollection] { get set } 22 | var selectedAssetCollection: PhotoAssetCollection? { get set } 23 | init(config: PickerConfiguration) 24 | func reloadData() 25 | } 26 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/AlbumList/PhotoAlbumList.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoAlbumList.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/9. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol PhotoAlbumListDelegate: AnyObject { 12 | func albumList( 13 | _ albumList: PhotoAlbumList, 14 | didSelectAt index: Int, 15 | with assetCollection: PhotoAssetCollection 16 | ) 17 | } 18 | 19 | public protocol PhotoAlbumList: UIView { 20 | 21 | var delegate: PhotoAlbumListDelegate? { get set } 22 | 23 | /// 相册集合 24 | var assetCollections: [PhotoAssetCollection] { get set } 25 | 26 | /// 选中的相册 27 | var selectedAssetCollection: PhotoAssetCollection? { get set } 28 | 29 | /// 相册列表的边距 30 | var contentInset: UIEdgeInsets { get set } 31 | 32 | /// 中心位置相册 33 | var middleIndex: Int { get } 34 | 35 | /// isSplit: 是否使用了 UISplitViewControoler 36 | init(config: PickerConfiguration, isSplit: Bool) 37 | 38 | /// 滚动到指定位置 39 | func scroll(to index: Int, animated: Bool) 40 | 41 | /// 将选中相册的滚动到中心位置 42 | func scrollSelectToMiddle() 43 | 44 | /// 刷新列表 45 | func reloadData() 46 | } 47 | 48 | public extension PhotoAlbumList { 49 | var middleIndex: Int { 0 } 50 | } 51 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/PhotoControllerEvent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoControllerEvent.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/22. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol PhotoControllerEvent: AnyObject { 12 | func photoControllerDidFinish() 13 | func photoControllerDidCancel() 14 | } 15 | 16 | public extension PhotoControllerEvent { 17 | func photoControllerDidFinish() { } 18 | func photoControllerDidCancel() { } 19 | } 20 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/PhotoDeniedAuthorization.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoDeniedAuthorization.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/10. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol PhotoDeniedAuthorization: UIView { 12 | var pickerDelegate: PhotoControllerEvent? { get set } 13 | init(config: PickerConfiguration) 14 | } 15 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/PhotoList/PhotoPickerListAssets.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerListAssets.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/11. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol PhotoPickerListAssets { 12 | var filterOptions: PhotoPickerFilterSection.Options { get set } 13 | var assetResult: PhotoFetchAssetResult { get set } 14 | var assets: [PhotoAsset] { get set } 15 | var photoCount: Int { get set } 16 | var videoCount: Int { get set } 17 | } 18 | 19 | public protocol PhotoPickerListFetchAssets: PhotoPickerListAssets, PhotoPickerListCondition { 20 | func getAsset(for index: Int) -> PhotoAsset 21 | } 22 | 23 | public extension PhotoPickerListFetchAssets { 24 | func getAsset(for index: Int) -> PhotoAsset { 25 | let photoAsset: PhotoAsset 26 | if needOffset { 27 | photoAsset = assets[index - offsetIndex] 28 | }else { 29 | photoAsset = assets[index] 30 | } 31 | return photoAsset 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/PhotoList/PhotoPickerListConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerListConfig.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/13. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol PhotoPickerListConfig { 12 | var config: PhotoListConfiguration { get set } 13 | } 14 | 15 | public protocol PhotoPickerListPickerConfig { 16 | var pickerConfig: PickerConfiguration { get set } 17 | } 18 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/PhotoList/PhotoPickerNavigationTitle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerNavigationTitle.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/9. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol PhotoPickerNavigationTitle: UIView { 12 | 13 | var title: String? { get set } 14 | 15 | var titleColor: UIColor? { get set } 16 | 17 | var isSelected: Bool { get set } 18 | 19 | init(config: PickerConfiguration, isSplit: Bool) 20 | 21 | func addTarget(_ target: Any?, action: Selector) 22 | 23 | func updateFrame() 24 | } 25 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/PhotoNavigationItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerNavigationItem.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/16. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum PhotoNavigationItemType { 12 | case cancel 13 | // case select 14 | case filter 15 | case finish 16 | } 17 | 18 | public protocol PhotoNavigationItemDelegate: PhotoControllerEvent { 19 | func photoItem(_ photoItem: PhotoNavigationItem, didSelected isSelected: Bool) 20 | func photoItem(presentFilterAssets photoItem: PhotoNavigationItem, modalPresentationStyle: UIModalPresentationStyle) 21 | } 22 | 23 | public extension PhotoNavigationItemDelegate { 24 | func photoItem(_ photoItem: PhotoNavigationItem, didSelected isSelected: Bool) { } 25 | func photoItem(presentFilterAssets photoItem: PhotoNavigationItem, modalPresentationStyle: UIModalPresentationStyle) { } 26 | } 27 | 28 | public protocol PhotoNavigationItem: UIView, PhotoPickerDataStatus { 29 | 30 | var itemDelegate: PhotoNavigationItemDelegate? { get set} 31 | 32 | var isSelected: Bool { get set } 33 | 34 | var itemType: PhotoNavigationItemType { get } 35 | 36 | init(config: PickerConfiguration) 37 | 38 | } 39 | 40 | public extension PhotoNavigationItem { 41 | var isSelected: Bool { get { false } set { } } 42 | func selectedAssetDidChanged(_ photoAssets: [PhotoAsset]) { } 43 | } 44 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/PhotoPickerControllerFectch.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerControllerFectch.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/11. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol PhotoPickerControllerViewFectch: UIView { 12 | var pickerController: PhotoPickerController { get } 13 | } 14 | public extension PhotoPickerControllerViewFectch { 15 | var pickerController: PhotoPickerController { 16 | if !Thread.isMainThread { 17 | assertionFailure() 18 | } 19 | guard let controller = viewController?.navigationController as? PhotoPickerController else { 20 | return .init() 21 | } 22 | return controller 23 | } 24 | } 25 | 26 | public protocol PhotoPickerControllerFectch: UIViewController { 27 | var pickerController: PhotoPickerController { get } 28 | } 29 | public extension PhotoPickerControllerFectch { 30 | var pickerController: PhotoPickerController { 31 | if !Thread.isMainThread { 32 | assertionFailure() 33 | } 34 | guard let controller = navigationController as? PhotoPickerController else { 35 | return .init() 36 | } 37 | return controller 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Protocol/UI/PhotoPickerDataStatus.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerDataStatus.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/22. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol PhotoPickerDataStatus { 12 | func selectedAssetDidChanged(_ photoAssets: [PhotoAsset]) 13 | } 14 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/Util/Picker+PhotoManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Picker+PhotoManager.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2020/12/29. 6 | // Copyright © 2020 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | import PhotosUI 12 | 13 | extension PhotoManager { 14 | 15 | func registerPhotoChangeObserver() { 16 | let status = AssetPermissionsUtil.authorizationStatus 17 | if status == .notDetermined || status == .denied { 18 | return 19 | } 20 | if isCacheCameraAlbum { 21 | if didRegisterObserver { 22 | return 23 | } 24 | PHPhotoLibrary.shared().register(self) 25 | didRegisterObserver = true 26 | }else { 27 | if !didRegisterObserver { 28 | return 29 | } 30 | PHPhotoLibrary.shared().unregisterChangeObserver(self) 31 | cameraAlbumResult = nil 32 | cameraAlbumResultOptions = nil 33 | didRegisterObserver = false 34 | } 35 | } 36 | } 37 | 38 | extension PhotoManager: PHPhotoLibraryChangeObserver { 39 | public func photoLibraryDidChange(_ changeInstance: PHChange) { 40 | guard let fetchResult = cameraAlbumResult, 41 | let changeResult = changeInstance.changeDetails(for: fetchResult) else { 42 | return 43 | } 44 | let result = changeResult.fetchResultAfterChanges 45 | cameraAlbumResult = result 46 | PhotoManager.shared.firstLoadAssets = true 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/View/Cell/Album/AlbumViewBaseCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumViewBaseCell.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/9. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class AlbumViewBaseCell: UITableViewCell { 12 | open var assetCollection: PhotoAssetCollection! 13 | 14 | open var config: AlbumListConfiguration = .init() 15 | 16 | open func updateSelectedStatus(_ isSelected: Bool) { } 17 | } 18 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/View/Cell/PhotoLoadingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoLoadingView.swift 3 | // HXPhotoPickerExample 4 | // 5 | // Created by Silence on 2023/6/17. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PhotoLoadingView: UIView { 12 | 13 | private var loadingView: ProgressIndefiniteView! 14 | 15 | override init(frame: CGRect) { 16 | super.init(frame: frame) 17 | backgroundColor = .black.withAlphaComponent(0.6) 18 | loadingView = ProgressIndefiniteView(frame: .init(origin: .zero, size: .init(width: 20, height: 20))) 19 | addSubview(loadingView) 20 | } 21 | 22 | var progress: CGFloat = 0 { 23 | didSet { 24 | if loadingView.isAnimating { 25 | loadingView.stopAnimating() 26 | } 27 | if loadingView.circleLayer.mask != nil { 28 | loadingView.circleLayer.mask = nil 29 | } 30 | loadingView.progress = progress 31 | } 32 | } 33 | 34 | func startAnimating() { 35 | loadingView.stopAnimating() 36 | loadingView.resetMask() 37 | loadingView.startAnimating() 38 | } 39 | 40 | func stopAnimating() { 41 | loadingView.stopAnimating() 42 | } 43 | 44 | override func layoutSubviews() { 45 | super.layoutSubviews() 46 | loadingView.center = .init(x: width / 2, y: height / 2) 47 | } 48 | 49 | required init?(coder: NSCoder) { 50 | fatalError("init(coder:) has not been implemented") 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/View/Cell/PhotoPickerWeChatViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerWeChatViewCell.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/10/25. 6 | // 7 | 8 | import UIKit 9 | 10 | open class PhotoPickerWeChatViewCell: PhotoPickerSelectableViewCell { 11 | 12 | public var titleLb: UILabel! 13 | 14 | open override func initView() { 15 | super.initView() 16 | titleLb = UILabel() 17 | titleLb.hxpicker_alignment = .center 18 | titleLb.textColor = .white 19 | titleLb.font = .semiboldPingFang(ofSize: 15) 20 | titleLb.isHidden = true 21 | contentView.insertSubview(titleLb, belowSubview: selectControl) 22 | } 23 | 24 | open override func updateSelectedState(isSelected: Bool, animated: Bool) { 25 | super.updateSelectedState(isSelected: isSelected, animated: animated) 26 | titleLb.isHidden = !isSelected 27 | titleLb.text = "\(photoAsset.selectIndex + 1)" 28 | titleLb.height = 18 29 | titleLb.width = titleLb.textWidth 30 | titleLb.centerY = selectControl.centerY 31 | } 32 | 33 | open override func layoutView() { 34 | super.layoutView() 35 | titleLb.hxPicker_x = 10 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/View/Cell/PreviewPhotoViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PreviewPhotoViewCell.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2021/3/12. 6 | // 7 | 8 | import UIKit 9 | 10 | class PreviewPhotoViewCell: PhotoPreviewViewCell, PhotoPreviewContentViewDelete { 11 | 12 | override init(frame: CGRect) { 13 | super.init(frame: frame) 14 | scrollContentView = PhotoPreviewContentPhotoView() 15 | scrollContentView.delegate = self 16 | initView() 17 | } 18 | required init?(coder: NSCoder) { 19 | fatalError("init(coder:) has not been implemented") 20 | } 21 | func contentView(requestSucceed contentView: PhotoPreviewContentViewProtocol) { 22 | delegate?.cell(requestSucceed: self) 23 | } 24 | func contentView(requestFailed contentView: PhotoPreviewContentViewProtocol) { 25 | delegate?.cell(requestFailed: self) 26 | } 27 | func contentView(updateContentSize contentView: PhotoPreviewContentViewProtocol) { 28 | setupScrollViewContentSize() 29 | } 30 | 31 | func contentView(networkImagedownloadSuccess contentView: PhotoPreviewContentViewProtocol) { 32 | delegate?.photoCell(networkImagedownloadSuccess: self) 33 | } 34 | func contentView(networkImagedownloadFailed contentView: PhotoPreviewContentViewProtocol) { 35 | delegate?.photoCell(networkImagedownloadFailed: self) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/View/Kit/TickView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TickView.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2020/12/29. 6 | // Copyright © 2020 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TickView: UIView { 12 | 13 | var tickLayer: CAShapeLayer! 14 | 15 | override init(frame: CGRect) { 16 | super.init(frame: frame) 17 | tickLayer = CAShapeLayer.init() 18 | tickLayer.contentsScale = UIScreen._scale 19 | let tickPath = UIBezierPath.init() 20 | tickPath.move(to: CGPoint(x: scale(8), y: height * 0.5 + scale(1))) 21 | tickPath.addLine(to: CGPoint(x: width * 0.5 - scale(2), y: height - scale(8))) 22 | tickPath.addLine(to: CGPoint(x: width - scale(7), y: scale(9))) 23 | tickLayer.path = tickPath.cgPath 24 | tickLayer.lineWidth = 1.5 25 | tickLayer.strokeColor = UIColor.black.cgColor 26 | tickLayer.fillColor = UIColor.clear.cgColor 27 | 28 | layer.addSublayer(tickLayer) 29 | } 30 | 31 | private func scale(_ numerator: CGFloat) -> CGFloat { 32 | return numerator / 30 * height 33 | } 34 | 35 | required init?(coder: NSCoder) { 36 | fatalError("init(coder:) has not been implemented") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Picker/View/ToolBar/PhotoToolBarEmptyView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoToolBarEmptyView.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Silence on 2023/10/16. 6 | // Copyright © 2023 Silence. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PhotoToolBarEmptyView: UIView, PhotoToolBar { 12 | public weak var toolbarDelegate: PhotoToolBarDelegate? 13 | public var toolbarHeight: CGFloat { 0 } 14 | public var viewHeight: CGFloat { 0 } 15 | public required init(_ config: PickerConfiguration, type: PhotoToolBarType) { 16 | super.init(frame: .zero) 17 | } 18 | 19 | required init?(coder: NSCoder) { 20 | fatalError("init(coder:) has not been implemented") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/ar.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/ar.lproj/Localizable.strings -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/de.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/de.lproj/Localizable.strings -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/es.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/es.lproj/Localizable.strings -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/fr.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/fr.lproj/Localizable.strings -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_camera_down_back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_camera_down_back@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_camera_down_back@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_camera_down_back@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_camera_overturn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_camera_overturn@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_camera_overturn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_camera_overturn@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_box_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_box_normal@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_box_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_box_normal@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_box_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_box_selected@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_box_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_box_selected@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_brush_color_custom@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_brush_color_custom@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_brush_color_custom@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_brush_color_custom@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_brush_repeal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_brush_repeal@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_brush_repeal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_brush_repeal@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_redo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_redo@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_redo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_redo@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_undo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_undo@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_undo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_undo@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_undo_all@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_undo_all@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_undo_all@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_canvas_draw_undo_all@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_mask_list@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_mask_list@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_mask_list@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_mask_list@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_left@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_left@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_left@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_left@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_left_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_left_selected@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_left_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_left_selected@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_right@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_right@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_right_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_right_selected@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_right_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_crop_scale_switch_right_selected@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_brightness@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_brightness@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_brightness@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_brightness@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_contrast@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_contrast@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_contrast@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_contrast@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_exposure@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_exposure@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_exposure@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_exposure@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_highlights@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_highlights@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_highlights@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_highlights@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_saturation@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_saturation@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_saturation@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_saturation@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_shadows@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_shadows@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_shadows@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_shadows@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_sharpen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_sharpen@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_sharpen@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_sharpen@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_vignette@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_vignette@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_vignette@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_vignette@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_warmth@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_warmth@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_warmth@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_filter_edit_warmth@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_mosaic_brush_image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_mosaic_brush_image@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_mosaic_brush_image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_mosaic_brush_image@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_crop@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_crop@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_crop@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_crop@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_mirror_horizontally@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_mirror_horizontally@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_mirror_horizontally@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_mirror_horizontally@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_mirror_vertically@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_mirror_vertically@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_mirror_vertically@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_mirror_vertically@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_rotate_left@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_rotate_left@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_rotate_left@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_rotate_left@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_rotate_right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_rotate_right@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_rotate_right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_rotate_right@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_text_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_text_normal@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_text_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_text_normal@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_text_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_text_selected@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_text_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_text_selected@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_tools_emoji@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_tools_emoji@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_tools_emoji@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_tools_emoji@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_tools_text@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_tools_text@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_tools_text@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_tools_text@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_trash_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_trash_close@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_trash_close@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_trash_close@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_trash_open@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_trash_open@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_trash_open@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_photo_trash_open@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tool_mosaic_color@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tool_mosaic_color@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tool_mosaic_color@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tool_mosaic_color@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tool_mosaic_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tool_mosaic_normal@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tool_mosaic_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tool_mosaic_normal@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_chartle_album@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_chartle_album@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_chartle_album@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_chartle_album@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_change@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_change@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_change@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_change@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_edit@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_edit@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_edit@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_edit@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_reset@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_reset@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_reset@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_filter_reset@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_graffiti@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_graffiti@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_graffiti@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_graffiti@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_mosaic@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_mosaic@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_mosaic@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_mosaic@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_music@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_music@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_music@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_music@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_play@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_play@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_play@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_tools_play@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_arrow_left@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_arrow_left@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_arrow_left@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_arrow_left@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_arrow_right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_arrow_right@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_arrow_right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_arrow_right@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_pause@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_pause@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_pause@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_pause@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_play@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_play@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_play@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_control_play@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_music_search@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_music_search@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_music_search@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_music_search@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_music_volume@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_music_volume@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_music_volume@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_video_music_volume@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_delete@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_delete@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_delete@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_delete@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_rotate@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_rotate@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_rotate@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_rotate@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_scale@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_scale@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_scale@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_editor_view_sticker_item_scale@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_edit_pull_down@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_edit_pull_down@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_edit_pull_down@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_edit_pull_down@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_any@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_any@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_any@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_any@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_edited@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_edited@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_edited@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_edited@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_gif@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_gif@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_gif@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_gif@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_livePhoto@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_livePhoto@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_livePhoto@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_livePhoto@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_photo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_photo@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_photo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_photo@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_video@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_video@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_video@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_photo_list_filter_video@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_album_empty@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_album_empty@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_album_empty@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_album_empty@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_photo_edit_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_photo_edit_icon@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_photo_edit_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_photo_edit_icon@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_edit_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_edit_icon@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_edit_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_edit_icon@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_icon@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_icon@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_play@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_play@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_play@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_cell_video_play@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_livePhoto@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_livePhoto@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_livePhoto@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_livePhoto@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_notAuthorized_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_notAuthorized_close@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_notAuthorized_close@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_notAuthorized_close@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_notAuthorized_close_dark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_notAuthorized_close_dark@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_notAuthorized_close_dark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_notAuthorized_close_dark@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photoList_photograph@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photoList_photograph@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photoList_photograph@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photoList_photograph@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photoList_photograph_white@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photoList_photograph_white@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photoList_photograph_white@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photoList_photograph_white@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photo_icloud_mark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photo_icloud_mark@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photo_icloud_mark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photo_icloud_mark@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_back@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_back@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_back@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_bottom_prompt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_bottom_prompt@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_bottom_prompt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_bottom_prompt@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_bottom_prompt_arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_bottom_prompt_arrow@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_bottom_prompt_arrow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_bottom_prompt_arrow@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_cancel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_cancel@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_cancel@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_cancel@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_nav_filter_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_nav_filter_normal@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_nav_filter_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_nav_filter_normal@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_nav_filter_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_nav_filter_selected@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_nav_filter_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_photolist_nav_filter_selected@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_toolbar_select_cell_delete@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_toolbar_select_cell_delete@2x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_toolbar_select_cell_delete@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/images/hx_picker_toolbar_select_cell_delete@3x.png -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/metal/hx_default.metallib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/metal/hx_default.metallib -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/musics/天外来物: -------------------------------------------------------------------------------- 1 | [ti:天外来物] 2 | [t_time:(00:38)] 3 | [00:00.000]你像 天外来物一样 求之不得 4 | [00:07.689]你在世俗里的名字 不重要了 5 | [00:14.689]正好 我隐藏的人格是契而不舍 6 | [00:21.689]直到蜂拥而至的人都透明了 7 | [00:28.689]我在 不近又不远处 8 | [00:33.189]用明天换你 靠近我 9 | -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/pt.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/pt.lproj/Localizable.strings -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/ru.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/ru.lproj/Localizable.strings -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Sources/HXPhotoPicker/Resources/HXPhotoPicker.bundle/zh-Hans.lproj/Localizable.strings -------------------------------------------------------------------------------- /Sources/HXPhotoPicker/Resources/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyCollectedDataTypes 6 | 7 | NSPrivacyAccessedAPITypes 8 | 9 | 10 | NSPrivacyAccessedAPIType 11 | NSPrivacyAccessedAPICategoryFileTimestamp 12 | NSPrivacyAccessedAPITypeReasons 13 | 14 | 3B52.1 15 | 16 | 17 | 18 | NSPrivacyAccessedAPIType 19 | NSPrivacyAccessedAPICategoryUserDefaults 20 | NSPrivacyAccessedAPITypeReasons 21 | 22 | CA92.1 23 | 24 | 25 | 26 | NSPrivacyTrackingDomains 27 | 28 | NSPrivacyTracking 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Sources/ImageView/GIFImageView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GIFImageView.swift 3 | // HXPhotoPickerExample 4 | // 5 | // Created by Silence on 2025/2/26. 6 | // Copyright © 2025 Silence. All rights reserved. 7 | // 8 | 9 | #if canImport(SwiftyGif) && HXPICKER_ENABLE_CORE 10 | import UIKit 11 | import SwiftyGif 12 | 13 | public class GIFImageView: UIImageView, HXImageViewProtocol { 14 | 15 | public func setImageData(_ imageData: Data?) { 16 | guard let imageData else { 17 | clear() 18 | SwiftyGifManager.defaultManager.deleteImageView(self) 19 | image = nil 20 | return 21 | } 22 | if let image = try? UIImage(gifData: imageData) { 23 | setGifImage(image) 24 | }else { 25 | image = .init(data: imageData) 26 | } 27 | } 28 | 29 | public func _startAnimating() { 30 | startAnimatingGif() 31 | } 32 | 33 | public func _stopAnimating() { 34 | stopAnimatingGif() 35 | } 36 | } 37 | #endif 38 | -------------------------------------------------------------------------------- /Sources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Swift/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // HXPhotoPicker 4 | // 5 | // Created by Slience on 2020/12/30. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | let windows = UIWindow(frame: UIScreen.main.bounds) 18 | let homeController: HomeViewController 19 | if #available(iOS 13.0, *) { 20 | homeController = HomeViewController(style: .insetGrouped) 21 | } else { 22 | homeController = HomeViewController(style: .grouped) 23 | } 24 | let navigationController = UINavigationController(rootViewController: homeController) 25 | windows.rootViewController = navigationController 26 | windows.makeKeyAndVisible() 27 | self.window = windows 28 | return true 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Swift/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Swift/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Swift/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Swift/Assets.xcassets/hx_compose_delete.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hx_compose_delete@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Swift/Assets.xcassets/hx_compose_delete.imageset/hx_compose_delete@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Assets.xcassets/hx_compose_delete.imageset/hx_compose_delete@2x.png -------------------------------------------------------------------------------- /Swift/Assets.xcassets/hx_picker_add_img.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hx_picker_add_img@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Swift/Assets.xcassets/hx_picker_add_img.imageset/hx_picker_add_img@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Assets.xcassets/hx_picker_add_img.imageset/hx_picker_add_img@2x.png -------------------------------------------------------------------------------- /Swift/Assets.xcassets/hx_picker_cell_video_play.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hx_picker_cell_video_play@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Swift/Assets.xcassets/hx_picker_cell_video_play.imageset/hx_picker_cell_video_play@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Assets.xcassets/hx_picker_cell_video_play.imageset/hx_picker_cell_video_play@2x.png -------------------------------------------------------------------------------- /Swift/Assets.xcassets/hx_sticker_cover.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hx_sticker_cover@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Swift/Assets.xcassets/hx_sticker_cover.imageset/hx_sticker_cover@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Assets.xcassets/hx_sticker_cover.imageset/hx_sticker_cover@2x.png -------------------------------------------------------------------------------- /Swift/Assets.xcassets/select_photo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "select_photo@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Swift/Assets.xcassets/select_photo.imageset/select_photo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Assets.xcassets/select_photo.imageset/select_photo@2x.png -------------------------------------------------------------------------------- /Swift/Classes/Extension/Core+UIColor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Core+UIColor.swift 3 | // Example 4 | // 5 | // Created by Slience on 2021/3/16. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIColor { 11 | 12 | convenience init(hexString: String) { 13 | let hexString = hexString.trimmingCharacters(in: .whitespacesAndNewlines) 14 | let scanner = Scanner(string: hexString) 15 | if hexString.hasPrefix("#") { 16 | scanner.scanLocation = 1 17 | } 18 | var color: UInt32 = 0 19 | scanner.scanHexInt32(&color) 20 | let mask = 0x000000FF 21 | let r = Int(color >> 16) & mask 22 | let g = Int(color >> 8) & mask 23 | let b = Int(color) & mask 24 | let red = CGFloat(r) / 255.0 25 | let green = CGFloat(g) / 255.0 26 | let blue = CGFloat(b) / 255.0 27 | self.init(red: red, green: green, blue: blue, alpha: 1) 28 | } 29 | class var systemTintColor: UIColor { 30 | UIColor.init(red: 0, green: 0.47843137254901963, blue: 1, alpha: 1) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Swift/Classes/Extension/RowTypeRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RowTypeRule.swift 3 | // Example 4 | // 5 | // Created by Slience on 2021/3/16. 6 | // 7 | 8 | import UIKit 9 | 10 | protocol HomeRowTypeRule { 11 | var title: String { get } 12 | var controller: UIViewController { get } 13 | } 14 | 15 | protocol ConfigRowTypeRule { 16 | var title: String { get } 17 | var detailTitle: String { get } 18 | 19 | func getFunction(_ controller: T) -> ((IndexPath) -> Void) 20 | } 21 | -------------------------------------------------------------------------------- /Swift/Classes/Extension/UIFont+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+Extension.swift 3 | // Example 4 | // 5 | // Created by Slience on 2021/1/13. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIFont { 11 | static func regularPingFang(ofSize size: CGFloat) -> UIFont { 12 | let font = UIFont.init(name: "PingFangSC-Regular", size: size) 13 | return font ?? UIFont.systemFont(ofSize: size) 14 | } 15 | static func mediumPingFang(ofSize size: CGFloat) -> UIFont { 16 | let font = UIFont.init(name: "PingFangSC-Medium", size: size) 17 | return font ?? UIFont.systemFont(ofSize: size) 18 | } 19 | static func semiboldPingFang(ofSize size: CGFloat) -> UIFont { 20 | let font = UIFont.init(name: "PingFangSC-Semibold", size: size) 21 | return font ?? UIFont.systemFont(ofSize: size) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Swift/Classes/Model/GPUImageBeautifyFilter.h: -------------------------------------------------------------------------------- 1 | // 2 | // GPUImageBeautifyFilter.h 3 | // BeautifyFaceDemo 4 | // 5 | // Created by guikz on 16/4/28. 6 | // Copyright © 2016年 guikz. All rights reserved. 7 | // 8 | 9 | #if __has_include() 10 | #import "GPUImage/GPUImage.h" 11 | 12 | @class GPUImageCombinationFilter; 13 | 14 | @interface GPUImageBeautifyFilter : GPUImageFilterGroup { 15 | GPUImageBilateralFilter *bilateralFilter; 16 | GPUImageCannyEdgeDetectionFilter *cannyEdgeFilter; 17 | GPUImageCombinationFilter *combinationFilter; 18 | GPUImageHSBFilter *hsbFilter; 19 | } 20 | 21 | //设置美化强度 22 | - (id)initWithDegree:(float)degree; 23 | 24 | @end 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /Swift/Classes/Model/ImageFilter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageFilter.swift 3 | // Example 4 | // 5 | // Created by Slience on 2022/2/18. 6 | // 7 | 8 | #if canImport(GPUImage) 9 | import UIKit 10 | import VideoToolbox 11 | import HXPhotoPicker 12 | import GPUImage 13 | 14 | struct FilterTools { 15 | static func filters() -> [CameraFilter] { 16 | [ 17 | BeautifyFilter(), InstantFilter(), Apply1977Filter(), ToasterFilter(), TransferFilter() 18 | ] 19 | } 20 | } 21 | 22 | class BeautifyFilter: CameraFilter { 23 | var filterName: String { 24 | return "美白" 25 | } 26 | 27 | var filter: GPUImageBeautifyFilter? 28 | 29 | func prepare(_ size: CGSize) { 30 | filter = GPUImageBeautifyFilter(degree: 0.6) 31 | } 32 | 33 | func render(_ pixelBuffer: CVPixelBuffer) -> CIImage? { 34 | var cgImage: CGImage? 35 | VTCreateCGImageFromCVPixelBuffer(pixelBuffer, options: nil, imageOut: &cgImage) 36 | guard let cgImage = cgImage, let bilateralFilter = filter else { 37 | return nil 38 | } 39 | let picture = GPUImagePicture(cgImage: cgImage) 40 | picture?.addTarget(bilateralFilter) 41 | bilateralFilter.useNextFrameForImageCapture() 42 | picture?.processImage() 43 | let result = bilateralFilter.newCGImageFromCurrentlyProcessedOutput().takeRetainedValue() 44 | return .init(cgImage: result) 45 | } 46 | 47 | func reset() { 48 | filter = nil 49 | } 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /Swift/Classes/Model/Tools.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tools.swift 3 | // Example 4 | // 5 | // Created by Silence on 2023/5/31. 6 | // 7 | 8 | import UIKit 9 | import HXPhotoPicker 10 | 11 | struct Tools { 12 | 13 | static var musicInfos: [VideoEditorMusicInfo] { 14 | var musics: [VideoEditorMusicInfo] = [] 15 | 16 | // let lyricUrl1 = Bundle.main.url(forResource: "天外来物", withExtension: nil)! 17 | // let lrc1 = try! String(contentsOfFile: lyricUrl1.path) // swiftlint:disable:this force_try 18 | // let music1 = VideoEditorMusicInfo(audioURL: .network(url: URL(string: "http://tsnrhapp.oss-cn-hangzhou.aliyuncs.com/chartle/%E5%A4%A9%E5%A4%96%E6%9D%A5%E7%89%A9.mp3")!), // swiftlint:disable:this line_length 19 | // lrc: lrc1) 20 | // musics.append(music1) 21 | 22 | let lyricUrl7 = Bundle.main.url(forResource: "世间美好与你环环相扣", withExtension: nil)! 23 | let lrc7 = try! String(contentsOfFile: lyricUrl7.path) // swiftlint:disable:this force_try 24 | let music7 = VideoEditorMusicInfo.init(audioURL: .bundle(resource: "世间美好与你环环相扣", type: "mp3"), 25 | lrc: lrc7) 26 | musics.append(music7) 27 | return musics 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Swift/Classes/View/CustomPickerCellView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPickerCellView.swift 3 | // Example 4 | // 5 | // Created by Slience on 2021/3/16. 6 | // 7 | 8 | import UIKit 9 | import HXPhotoPicker 10 | 11 | class CustomPickerViewCell: PhotoPickerViewCell { 12 | lazy var selectedMaskView: UIView = { 13 | let view = UIView.init() 14 | view.layer.borderWidth = 5 15 | view.layer.borderColor = UIColor(hexString: "#07c160").cgColor 16 | view.backgroundColor = UIColor.black.withAlphaComponent(0.6) 17 | view.addSubview(numberLb) 18 | view.isHidden = true 19 | return view 20 | }() 21 | 22 | lazy var numberLb: UILabel = { 23 | let label = UILabel.init() 24 | label.textColor = UIColor(hexString: "#ffffff") 25 | label.textAlignment = .center 26 | label.font = .boldSystemFont(ofSize: 35) 27 | label.adjustsFontSizeToFitWidth = true 28 | return label 29 | }() 30 | 31 | override func initView() { 32 | super.initView() 33 | contentView.addSubview(selectedMaskView) 34 | } 35 | 36 | override func updateSelectedState(isSelected: Bool, animated: Bool) { 37 | super.updateSelectedState(isSelected: isSelected, animated: animated) 38 | numberLb.text = String(photoAsset.selectIndex + 1) 39 | selectedMaskView.isHidden = !isSelected 40 | } 41 | 42 | override func layoutView() { 43 | super.layoutView() 44 | selectedMaskView.frame = bounds 45 | numberLb.frame = selectedMaskView.bounds 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Swift/HXPHPickerExample-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "GPUImageBeautifyFilter.h" 6 | -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_chongya.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_chongya.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_haoxinqing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_haoxinqing.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_housailei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_housailei.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_jintianfenkeai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_jintianfenkeai.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_keaibiaoq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_keaibiaoq.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_kehaixing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_kehaixing.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_saihong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_saihong.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_wow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_wow.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_woxiangfazipai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_woxiangfazipai.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_xiaochuzhujiao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_xiaochuzhujiao.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_yuanqimanman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_yuanqimanman.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_yuanqishaonv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_yuanqishaonv.png -------------------------------------------------------------------------------- /Swift/Images/hx_sticker_zaizaijia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/hx_sticker_zaizaijia.png -------------------------------------------------------------------------------- /Swift/Images/livephoto_image.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/livephoto_image.jpeg -------------------------------------------------------------------------------- /Swift/Images/love.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/love.png -------------------------------------------------------------------------------- /Swift/Images/love_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/love_text.png -------------------------------------------------------------------------------- /Swift/Images/portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/portrait.png -------------------------------------------------------------------------------- /Swift/Images/qiy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/qiy.png -------------------------------------------------------------------------------- /Swift/Images/stars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/stars.png -------------------------------------------------------------------------------- /Swift/Images/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Images/text.png -------------------------------------------------------------------------------- /Swift/Music/世间美好与你环环相扣: -------------------------------------------------------------------------------- 1 | [ti:世间美好与你环环相扣] 2 | [ar:妮达Anita] 3 | [al:妮达COVER片段合辑] 4 | [t_time:(00:31)] 5 | [00:02.44]此时已莺飞草长爱的人正在路上 6 | [00:06.502]我知他风雨兼程途经日暮不赏 7 | [00:10.510]穿越人海只为与你相拥 8 | [00:16.53]此刻已皓月当空爱的人手捧星光 9 | [00:20.530]我知他乘风破浪去了黑暗一趟 10 | [00:24.538]感同身受给你救赎热望 11 | -------------------------------------------------------------------------------- /Swift/Music/世间美好与你环环相扣.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceLove/HXPhotoPicker/863bf0ea55d9403762c91971493f1244b701253e/Swift/Music/世间美好与你环环相扣.mp3 -------------------------------------------------------------------------------- /Swift/ar.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SwiftUI/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SwiftUI/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUI/ConfigView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConfigView.swift 3 | // SwiftUIExample 4 | // 5 | // Created by Silence on 2023/9/9. 6 | // Copyright © 2023 洪欣. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import UIKit 11 | import HXPhotoPicker 12 | 13 | @available(iOS 13.0, *) 14 | struct ConfigView: UIViewControllerRepresentable { 15 | 16 | @Binding var config: PickerConfiguration 17 | 18 | func makeUIViewController(context: Context) -> UINavigationController { 19 | let vc = PickerConfigurationViewController(style: .insetGrouped) 20 | vc.showOpenPickerButton = false 21 | vc.config = config 22 | vc.didDoneHandler = { config, _ in 23 | self.config = config 24 | } 25 | return UINavigationController.init(rootViewController: vc) 26 | } 27 | 28 | func updateUIViewController(_ configVC: UINavigationController, context: Context) { 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /SwiftUI/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIExampleApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftUIExampleApp.swift 3 | // SwiftUIExample 4 | // 5 | // Created by Silence on 2023/9/8. 6 | // Copyright © 2023 洪欣. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | @main 12 | struct SwiftUIExampleApp: App { 13 | var body: some Scene { 14 | WindowGroup { 15 | ContentView(photoAssets: [], assets: []) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tmp.xcconfig: -------------------------------------------------------------------------------- 1 | EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64=arm64 arm64e armv7 armv7s armv6 armv8\ 2 | EXCLUDED_ARCHS=$(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT))} 3 | --------------------------------------------------------------------------------