Приложение macOS для создания серии скриншотов из видео файла.
GrabShotReview.mov
В работе медиа, при планировании рекламных роликов и фильмов, требуется создание мудборд презентаций. Презентации состоят обычно из кадров других похожих работ. Чтоб облегчить поиск и время на отсмотр вдохновляющих материалов, я решил написать приложение которое автоматизирует этот процесс. Исходные навыки дала мне школа GeekBrains, где я учюсь на разработчика iOS приложений. Бибилотеки реализации приложений на iOS и macOS одни и теже, поэтому я решил написать такую утилиту.
- Импорт серии видео файлов в приложение
- Захват изображений с заданным интервалом
- Создание штрихкода цвета для видео
- Сохранение файлов захвата на диск
- Настройки для параметров захвата
На стадии задумки я хотел чтоб пользователь мог загрзить сразу серию видео файлов и самаы быстрым и понятным способом оказался - Drag&Drop. Поэтому первое окно при запуске - это поле куда пользователь может перетащить видео файлы.
![Drop](https://private-user-images.githubusercontent.com/65191747/246842902-a0ee590b-201f-4da0-bfeb-c4bb1c23dea4.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNDY4NDI5MDItYTBlZTU5MGItMjAxZi00ZGEwLWJmZWItYzRiYjFjMjNkZWE0LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTgyZjNjYTM4ODZiODc2YTExMmM4ZTUzZTEzYTk3YWM4ZDI2MjEzOTljZGFlYWFmODAxNzhhNTVlMjc5ZDU5ZjkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.u4USLdA6Fk4CqXCM7rRJodQdZ-sUlpdpSyM4z-4R5HE)
Так же есть классический способ выбрать файл через панель навигации приложения сверху "Файл -> Выбрать Видео" или горячие клавиши ⌘ + O.
![Import](https://private-user-images.githubusercontent.com/65191747/246844104-63954553-960a-43bc-8793-0f82703190b0.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNDY4NDQxMDQtNjM5NTQ1NTMtOTYwYS00M2JjLTg3OTMtMGY4MjcwMzE5MGIwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWE2MTk1ZjFlNzg3NTFmYzFhYTdiZmM1Y2VmY2YzNTdlNWY4MzYyZjcyZGVhYTVmMjNiNGU5NTBkOWVhNWNiMTgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.EkZJ-E1nqiwlgJVQHlSpPR1KlLzKuLdA1kekC8kpUz8)
На панели навигации приложения есть элемент с вкладками, чтоб пользователь мог переключаться между рабочами окнами
После импорта видео файла, приложение автоматически переключается на вкладку захвата изображений. Здесь таблица, где мы видим выбранное видео с информацией расположения файла в виде ссылки, длительность, колличество кадров захвата на выходе при текущем интервале внизу и шкала прогресса. Ниже настроек есть поле для цветового штрихкода, которое будет динамически рисоваться с каждым кадром захвата. Barcode - это цветовая палитра кадров в фильме, она отражает цветовой характер использованных цветов и оттенков в произведении. На поле штрихкода есть кнопка для просмотра штрихкода. Последняя зона - это общий прогресс очереди захвата с кнопками запуска/остановки и отмены.
![2 GrabQueueTab](https://private-user-images.githubusercontent.com/65191747/260993754-eae52c78-ed0e-4f37-9884-8f4c9e5bdaf5.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNjA5OTM3NTQtZWFlNTJjNzgtZWQwZS00ZjM3LTk4ODQtOGY0YzllNWJkYWY1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTE5OGIwYzZjZDAwMDEzMjAwZWE3MmNjNGVlZDZiNjhiMDU3MmE1MzkxYjY3MWEwNjk0ZjViMmMyNTUwOTVlYmEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.fV2vaKlMMhPyHs0lM8YBBODQPs0BQVhxmwXSjDICuwU)
При запуске процесса по кнопке Старт, начинается захват кадров. Над школой прогресса есть лог описание что происходит в данный момент, какой текущий кадр и сколько их всего.
![3 Grabbing](https://private-user-images.githubusercontent.com/65191747/260993969-61917ae5-2a2b-498c-b6a0-d92f7459fb8f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNjA5OTM5NjktNjE5MTdhZTUtMmEyYi00OThjLWI2YTAtZDkyZjc0NTlmYjhmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTExZDZmY2I1ODNlYTkwZjg4N2U0OWU1MjUyZTFjNjEwMmY5MTlkYjBjZTM4ZDg4Yzc1OGY2OWNlMTVmNDk1YWYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.khYdp--Qb7g87P7WncvMbnd2q5wei358sULgEc2AbQw)
И конечно есть возможность сделать скриншоты для всех импортированных файлов. Прогресс в таблице показывает состояние каждого, а общий всей очереди.
![2 GrabQueueTab 2](https://private-user-images.githubusercontent.com/65191747/260994062-734bbe7c-f935-4b57-be26-23b587f2a284.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNjA5OTQwNjItNzM0YmJlN2MtZjkzNS00YjU3LWJlMjYtMjNiNTg3ZjJhMjg0LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTI1OGZiZjY3NWIyYTBjNDNmMTc4YmFjN2Q4ZmU0NGM2NTAyNGQ2MDQ3ZTk0MGQwOWExZjM5NmI2ZmUzZTA5NWUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.QDhyOaTPdwzOJwGa9E0K9jncWER11L4mkiUrp0WNnjc)
Получившиеся кадры в процессе сохраняются на диск в автоматически созданную папку с тем же названием что и видео файл. Местоположение папки то же что и файл. Название кадров - это название видео файла с суффиксом таймкода.
![Output](https://private-user-images.githubusercontent.com/65191747/246843009-e37c97a6-8c4c-4daf-9e03-f64dc378e3db.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNDY4NDMwMDktZTM3Yzk3YTYtOGM0Yy00ZGFmLTllMDMtZjY0ZGMzNzhlM2RiLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTU3ZWFlY2I2ZDE3YTY3Njc1MTZkNDVlMDk0YzgwOTZjODlkM2UxYTc3NTBmY2I5OWRjNzAxMmU5ZDk0MzlkZjImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.fS-G4wBCCRjtU0L6e4ueWzLe8RmmsHNeL1ctbVPbQQU)
Получившийся цветовой штрихкод можно посомтреть по кнопке на его поле. Файл сохраняется тоже в папку с кадрами.
![StripPreview](https://private-user-images.githubusercontent.com/65191747/246842946-f9ace501-0ec2-40ba-82cc-0b885420cac8.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNDY4NDI5NDYtZjlhY2U1MDEtMGVjMi00MGJhLTgyY2MtMGI4ODU0MjBjYWM4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTRhM2Y4NzRmOTM4M2IzYjdhYTYyMmVmYjFjZTlmMzIyYWUwN2RlMDY5NWZjYTNlYzgyZjU5ZDMzNjUxZGYzYzcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.gQrAIB5rHijJiHE7VRnKX3bnQF_x4E0C5PJVOxNyeJI)
Ниже приведены несколько штрихкодов из разных фильмов.
Работу приложения можно настроить. Запуск окна для этого лежит в интуитивном месте - в верхней панели системы по нажатию на назвние программы или комюинацией ⌘ + ,.
![SettingsNavigation](https://private-user-images.githubusercontent.com/65191747/246855576-2621377a-7cfc-40fc-a3f7-d7de4ac22fbf.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNDY4NTU1NzYtMjYyMTM3N2EtN2NmYy00MGZjLWEzZjctZDdkZTRhYzIyZmJmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPThjNDUxNmJmZGVkMWIyYWM5ZWM3ODliMzdjZWM2NDVlYmUwZTk5YWE1ZjAyNGQ5ZmI1NGNlMDJkMzQzNmQ4YjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.fS8VG6TlG1ORXNMloHDYZbR8gvC5r541DOCYK2EYFGU)
Окно настроек делится на две вкладки.
Здесь есть ползунок для выбора степени сжатия JPG ихображений. И переключатель открытия папки с получишимися изображениями в финале процесса захвата.
![GrabSettings](https://private-user-images.githubusercontent.com/65191747/246843842-e9852f33-9762-4332-886b-ec74a0b3d87b.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNDY4NDM4NDItZTk4NTJmMzMtOTc2Mi00MzMyLTg4NmItZWM3NGEwYjNkODdiLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTc2N2UyNzA4M2UyODk0NzQ2MTgxMjQ1MjFkZjZlZDVjZDRhZjYwMDJjM2E4YjA0MTc4MWNlMjBkZDM2OTgwNWUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.GIMKWs1aS0QTOocShddqoT4pmRmQtwLLiWSX45Kil3M)
Штрихкод нужен для разных задач и какой он должен быть - должен определит пользователь. На каждом кадре определяется средний цвет или цвета, их колличество можно выбрать. Разрешение конечного изображения может понадобится большим или наоборот маленьким, поэтому есть поля для размера в пикселях.
![StripSettings](https://private-user-images.githubusercontent.com/65191747/246843855-7071504d-94cc-4d28-8fbb-19edee3afb82.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNDY4NDM4NTUtNzA3MTUwNGQtOTRjYy00ZDI4LThmYmItMTllZGVlM2FmYjgyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTdlMzBkMTBkZjNjYjlkY2RhNjcwM2M3ZTYyN2JmZTkxYjE1MWVmMzU5OTEwYjcwZTZjYmIxMGUwNWMwNDIyNGEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.d2_heN9REr9oaVz2eCNao1_GDM3xTQxaz6UVfyCBVzg)
![Colors](https://private-user-images.githubusercontent.com/65191747/246843834-11ed2a66-ecb8-48d5-8616-0c563c68bef9.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNDY4NDM4MzQtMTFlZDJhNjYtZWNiOC00OGQ1LTg2MTYtMGM1NjNjNjhiZWY5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDAzMDkyOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWE0YTJiZWZhN2Y2NGQ2Mzk3ZGMxMTgxZGUxZGMwNjFjZTQ4NmZmNDY4NzVjODZhMjMyN2FiYTRhOGRiZDI3MTMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.laiH09Vf9dybw_LKufs-0j4zkZgw1VZQD_zPzSi0IWY)
Использованные ресурсы:
Интерфейс я решил написать на SwiftUI. Причины этого решения:
- Хотелось закрепить знания этого фреймворка, которые я получил в IT школе
- Приложение не сложное, поэтому проблемы нового фреймворка по отношению не должны были возникнуть
- Синтаксис фреймворка одинаковый для мобильных приложений и для macOS
- В SwiftUI есть предикаты, которые делают код реактивным, что уменбшает колличество кода
- Научится работать с предикатами на практике
Я провел поиск подходящего мультимедиа фремворка и рассматривал следующие:
Как правило весь видео материал кино и сериалов в сети формата MKV, а встреонный AVFoundation его не поддерживает и сразу отпал.
VLCKit поддерживает MKV имеет простую документацию, написан на Objective-C. Имопртируется Pod или Package Manager. Но возникла проблема в получении серии скриншотов, они дублировались по неизвестным причинам. То есть таймкод новый в функции, а библиотека выдает прошлый кадр.
Решил попробовать FFmpeg, тут сложнее, потому что общение с фреймфорком требуется через командую строку, но это возможно. На этот раз результат был всегда точный. Есть wrapper для удобного общения в FFmpeg. Я использовал FFmpegKit.
GrabShot/GrabShot/Service/VideoService/VideoService.swift
Lines 14 to 47 in 5892b10
Серия операций захвата создается через OperationQueue
Ниже код создания очереди операций. В каждой определен completion block который будет сообщать когда операция заврешилась.
GrabShot/GrabShot/Core/GrabOperationManager/GrabOperationManager.swift
Lines 82 to 108 in 5892b10
Сама операция захвата лежит в функции main объекта Operation
GrabShot/GrabShot/Core/GrabOperationManager/GrabOperation.swift
Lines 10 to 29 in 5892b10
Так как операция pахвата происходит асинхронно, то пришлось создасть свой класс AsyncOperation наслядуюсь от Operation:
GrabShot/GrabShot/Core/GrabOperationManager/AsyncOperation.swift
Lines 10 to 62 in 5892b10
Принцип создания не сложный. Опишу его. Цветовая палитра одного кадра - это набор нескольких прямоугольников с усредненными цветам кадра выстроенных по горизонтали. Например она может выглядеть так.
![ColotPalete](https://private-user-images.githubusercontent.com/65191747/246866843-394750a6-af01-4876-b861-a3567565180b.jpeg?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0MTY0NjgsIm5iZiI6MTczOTQxNjE2OCwicGF0aCI6Ii82NTE5MTc0Ny8yNDY4NjY4NDMtMzk0NzUwYTYtYWYwMS00ODc2LWI4NjEtYTM1Njc1NjUxODBiLmpwZWc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjEzJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxM1QwMzA5MjhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0yOWU1ZDI0OGE0OTY2MmZlMGUxYjc1ZGY2ZDk2OThmMDBiMzBlN2MyOWZjZGJhN2Q3ZTNmNGI4NTkyNDA2NGQ5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.aBvpmsZx_HSZrEql3ehAyOlPjRopKwCy0TuE1uAOZQM)
Если взять несколько таких палитр, выстроить их по горизонтали, то получится очень длинная полоса с цветовыми прямоугольниками. Далее надо их сжать до ширины экрана, чтоб видеть все сруз и вот получится цветовой штрихкод. Для создания такого изображения я использовал Core Image. Функция высчитывания средних цвета изображения
GrabShot/GrabShot/Helper/NSImageExtension.swift
Lines 29 to 56 in f98c89b
Получив координаты цвета в виде Color, я создаю привычное SwiftUI view через стек прямоугольников заполненых цветом. Которые пополняются по мере обноления модели Video.
GrabShot/GrabShot/View/Elements/StripView.swift
Lines 10 to 27 in f98c89b
Сохранить получившееся вью в изорбражение можно используя ImageRenderer
GrabShot/GrabShot/Model/StripModel.swift
Lines 18 to 38 in f98c89b
- Перенести создание скриншотов для поддерживаемых форматов на встроенную библиотеку AVFoundation