Helios - edytor zdjęć i plików RAW działający w przeglądarce

Nasz darmowy edytor zdjęć i plików RAW, który działa w całości w przeglądarce. Pokazujemy, jak otwieramy pliki z aparatów przez LibRaw w WebAssembly, jak liczymy podgląd na karcie graficznej i jak pilnujemy, żeby praca nigdy nie zginęła.
Kontekst projektu
Helios to darmowy edytor zdjęć w stylu Lightrooma, który otwierasz na arteontools.com jak zwykłą stronę. Otwiera zdjęcia z telefonu i pliki RAW z aparatów, poprawia światło i kolor, kadruje i prostuje, nakłada jeden ze 100 filtrów albo te same ustawienia na całą serię, a potem zapisuje wynik w siedmiu formatach. Pliki nie opuszczają Twojego urządzenia, a zapis nie wymaga konta ani opłaty.
Skąd wziął się pomysł na Helios?
Na arteontools.com stał wcześniej prosty edytor zdjęć. Umiał przyciąć zdjęcie do wybranego wymiaru i zapisać je w innym formacie, i na tym jego możliwości się kończyły. Chcieliśmy dać użytkownikom narzędzie, które rozjaśni ciemne zdjęcie, poprawi kolory i otworzy plik RAW prosto z aparatu, a do tego nie będzie wymagało instalowania programu.
Zanim napisaliśmy pierwszą linijkę kodu, przeczytaliśmy, na co narzekają ludzie korzystający z edytorów zdjęć. Przeanalizowaliśmy 18 754 recenzje z App Store w 15 krajach, wątki na forum Adobe, na Hacker News, na GitHubie i na forach fotograficznych w kilku językach. Najczęściej wracały te same sprawy:
- aplikacja pozwala edytować za darmo, a płacić każe dopiero przy zapisie, często w formie rocznej subskrypcji,
- do jednej szybkiej poprawki trzeba założyć konto,
- program chce dostępu do całej biblioteki zdjęć i wysyła pliki na serwer,
- funkcje AI pojawiają się na siłę, a kredyty na nie znikają,
- po aktualizacji przepada praca albo zapisane ustawienia,
- zdjęcie w zapisanym pliku wygląda inaczej niż na ekranie,
- program działa wolno, grzeje komputer i się zawiesza.
Z tych skarg wzięły się zasady Heliosa. Zapis jest zawsze darmowy, nie ma konta ani subskrypcji, a zdjęcia nie opuszczają przeglądarki. Nie używamy AI: przyciski Automatycznie i filtry liczą wynik klasycznymi metodami, które dają za każdym razem ten sam efekt. Reklamy stoją wyłącznie w bocznej kolumnie, tak jak w Photopei, i nigdy nie stają między kliknięciem Zapisz a plikiem na dysku. Tak powstał Helios, pierwszy z naszych większych programów. Każde takie narzędzie dostaje imię greckiego boga albo półboga, a Helios to w mitologii greckiej bóg słońca.
Co potrafi Helios?
Helios to edytor zdjęć w stylu Lightrooma, który otwierasz w przeglądarce jak zwykłą stronę. W skrócie:
- otwiera zdjęcia JPG, PNG, HEIC, WebP, AVIF, TIFF, GIF i BMP oraz pliki RAW z aparatów i telefonów, m.in. CR3, CR2, NEF, ARW, RAF, ORF, RW2 i DNG,
- ma sekcje Światło, Kolor, Mieszanie kolorów, Szczegóły, Gradacja kolorów i Efekty, a w sekcjach Światło i Kolor przycisk Automatycznie,
- kadruje zdjęcie w proporcjach Dowolne, Oryginalne, 1:1, 4:5, 3:2 i 16:9 i prostuje je ręcznie albo przyciskiem Wyprostuj automatycznie,
- ma 100 filtrów w dwunastu kategoriach i pozwala zapisać własne,
- przenosi ustawienia z jednego zdjęcia na całą serię i wyrównuje przy tym jasność i balans bieli,
- zapisuje wynik jako JPG, PNG, WebP, AVIF, TIFF, BMP albo GIF, a kilka zdjęć naraz w jednym pliku ZIP,
- zapisuje Twoją pracę w przeglądarce, więc po zamknięciu karty możesz do niej wrócić.
Pełną instrukcję obsługi, z opisem każdego suwaka i każdego komunikatu, znajdziesz na stronie Heliosa. Tutaj opowiadamy, jak go zbudowaliśmy i dlaczego działa tak, a nie inaczej.
Osobna kategoria dla większych programów
Helios nie pasował do żadnej z dotychczasowych kategorii. Zwykłe narzędzie Arteon robi jedną rzecz na jednej stronie, a Helios to cały program, który otwiera się na pełnym ekranie, pracuje na wielu plikach naraz, ma skróty klawiszowe i historię zmian. Dlatego dostał nową kategorię Zaawansowane, która stoi pierwsza od lewej w menu. Jej rozwijane menu pokazuje zrzut ekranu programu i dłuższy opis zamiast listy narzędzi, a strona kategorii ma kartę każdego programu z przyciskiem, który od razu go otwiera.

Pod adresem Heliosa stoi zwykła strona z treścią i instrukcją, w tym samym układzie co strony innych narzędzi. Sam edytor otwiera się pod tym samym adresem z dopiskiem #edytor na końcu. Dzięki temu Google widzi stronę z opisem, tabelami i odpowiedziami na pytania, a Ty jednym kliknięciem przechodzisz do pracy. Przycisk zamknięcia w edytorze wraca na stronę z instrukcją.

Jak otwieramy pliki RAW w przeglądarce?
Plik RAW to surowe dane z matrycy aparatu, a nie gotowe zdjęcie. Każdy producent zapisuje je inaczej, a nowe aparaty co chwilę zmieniają szczegóły formatu. Pisanie własnego dekodera dla kilkuset modeli nie miałoby sensu, więc sięgnęliśmy po LibRaw, otwartą bibliotekę w języku C, z której korzysta wiele programów do zdjęć. Używamy wersji 0.22.2, a co miesiąc sprawdzamy, czy wyszła nowa.
Przeglądarka nie uruchamia kodu w C, dlatego LibRaw kompilujemy do WebAssembly, czyli formatu, który przeglądarka wykonuje prawie tak szybko jak zwykły program. Najpierw sprawdziliśmy gotową paczkę libraw-wasm. Na serwerze deweloperskim działała, ale na produkcji przestała, bo uruchamiała kod z tekstu, a nagłówek Content Security Policy na arteontools.com słusznie tego zabrania. Zbudowaliśmy więc LibRaw sami, z przypiętą wersją kompilatora Emscripten, i wołamy go przez jego API w C, bez warstwy, która takiego kodu potrzebowała. Test na kodzie dekoderów pilnuje, żeby nic nie uruchamiało kodu z tekstu, a test na zbudowanej wersji produkcyjnej sprawdza dekodery pod tym samym nagłówkiem co na stronie.
Kompilacja powstaje w dwóch wariantach. Szybszy korzysta z instrukcji SIMD, które liczą kilka pikseli naraz. Drugi działa bez nich w Safari od 15.0 do 16.3, czyli na starszych iPhone'ach i Makach. Edytor sam sprawdza, który wariant obsłuży przeglądarka. Plik WebAssembly zawiera tylko niezmieniony LibRaw z bibliotekami, z których korzysta, a cały nasz kod stoi obok. Tak spełniamy warunki licencji CDDL 1.0, a pełne teksty licencji i archiwa źródeł leżą na stronie pod linkiem Licencje w edytorze.
Jeden wątek na zdjęcie i świadoma decyzja o reklamach
LibRaw potrafi dzielić pracę nad jednym zdjęciem między rdzenie procesora, ale w przeglądarce wymagałoby to nagłówków COOP i COEP. Z tymi nagłówkami nie działają reklamy, z których utrzymujemy wszystkie narzędzia, więc każde zdjęcie dekoduje jeden wątek, a z kilku rdzeni korzystamy inaczej: przy serii działa kilka dekoderów naraz, o czym piszemy niżej. Dekodowanie odbywa się w osobnym wątku przeglądarki (Web Workerze), więc strona nie zacina się nawet przy pliku 100 Mpx.
Matryca aparatu rejestruje w każdym pikselu tylko jeden kolor, a resztę trzeba policzyć z sąsiednich pikseli. Ten krok nazywa się demozaikowaniem. Dla zwykłej mozaiki Bayera używamy metody AHD, a dla matryc X-Trans z aparatów Fujifilm metody Markesteijna, która dobrze radzi sobie z ich nieregularnym układem kolorów.

Jak sprawiliśmy, że RAW pokazuje się po ułamku sekundy?
Pierwszy pomiar wypadł słabo. Plik CR3 z Canona R6 II pokazywał się po 1,52 s, plik ARW 61 Mpx z Sony A7R IV po 2,67 s, a seria 10 plików RAW wypełniała pasek miniatur przez ponad 16 sekund. Pomiar pokazał trzy przyczyny: LibRaw otwierał każdy plik dwa razy, seria dekodowała się po jednym pliku, a edytor nie korzystał z podglądu JPG, który aparat zapisuje w każdym pliku RAW.
Dziś podgląd z aparatu wyciągamy z samych nagłówków pliku, bez uruchamiania LibRaw. Napisaliśmy czytnik, który zna budowę plików CR2, NEF, ARW, DNG, ORF i PEF, pole z podglądem w RW2, pierwszą ścieżkę w CR3 i nagłówek RAF. Czyta tylko strukturę pliku i bajty podglądu, więc w Chromium mediana wynosi 0,12 s zamiast 0,26 s przez LibRaw. Po tej zmianie CR3 z Canona widać po 0,28 s, a ARW 61 Mpx po 0,17 s. Podgląd z aparatu ma obróbkę aparatu, a nie naszą, więc suwaki ruszają dopiero wtedy, gdy LibRaw wywoła cały plik.


Kilka dekoderów naraz przy serii
Wszystkie wybrane zdjęcia od razu stają w pasku miniatur, także te, które jeszcze czekają. Miniatury czekających plików powstają z podglądów aparatu, więc pasek zapełnia się w kilka sekund. Kliknięcie czekającego zdjęcia otwiera je jako następne, a zamknięcie przerywa jego dekodowanie.
Sprawdziliśmy, ile dekoderów naraz się opłaca. Trzy skróciły dekodowanie serii 10 plików RAW 2,3 raza w Chromium i 2,7 raza w Firefoksie. Czwarty dawał w Chromium jeszcze 16%, a w Firefoksie już spowalniał, a każdy dodatkowy dekoder zajmuje około 300–350 MB pamięci. Edytor dobiera więc liczbę dekoderów do komputera: bierze połowę liczby rdzeni procesora, najwyżej trzy, a przy 2 GB pamięci jeden. Pierwsze zdjęcie w pustym edytorze dekoduje się samo, bo na nie czekasz, a dopiero potem rusza reszta serii.


Dlaczego pliki RAW wywołujemy w 16 bitach?
W pierwszej wersji Helios zamieniał RAW na zwykły obraz 8-bitowy, taki jak JPG. To proste rozwiązanie, ale gubi to, po co w ogóle robi się zdjęcia w RAW. Jasne niebo, które w 8 bitach jest już czystą bielą, w danych z matrycy często ma jeszcze rysunek chmur. Dlatego od nowej wersji RAW idzie osobną drogą: dekoder oddaje liniowe dane z matrycy w 16 bitach na kanał, a podgląd trzyma je w liczbach połowy precyzji, w których biel to 1,0, a powyżej niej jest jeszcze zapas.
Różnicę zmierzyliśmy na prawdziwych plikach. Na zdjęciu z Canona R6 II po ustawieniu suwaka Światła na −100 sąsiednie piksele w miejscach, które w 8 bitach były całkiem białe, różnią się średnio o 1,27 poziomu jasności, a w 8 bitach o 0,36, bo tam zostaje jednolita szara plama. Na ciemnym, gładkim przejściu po ustawieniu Ekspozycji na +4 obraz w 8 bitach rozpada się na pasy, a 12% poziomów jasności zostaje pustych. W 16 bitach przejście zostaje gładkie.
Miejsca, w których matryca obcięła jeden kanał koloru, na przykład jasne niebo, wychodzą bez fioletowego zabarwienia, bo edytor miesza tam kolor z obciętych i nieobciętych kanałów. Na zerowych suwakach zdjęcie wygląda tak samo jak w 8 bitach: na zdjęciu z Pixela 7 Pro różnica wynosi średnio 0,32 ΔE, czyli poniżej różnicy, którą oko zauważa.
Ścieżka 16-bitowa zajmuje dwa razy więcej pamięci, więc edytor najpierw szacuje, czy zdjęcie się zmieści. Zakłada 36 MB na megapiksel i porównuje to z połową pamięci urządzenia. Zdjęcie 50 Mpx potrzebuje około 1,8 GB, więc na komputerze z 4 GB pamięci otworzy się w 16 bitach, a na takim z 2 GB w 8 bitach. To samo dzieje się, gdy przeglądarce zabraknie pamięci w trakcie pracy: zdjęcie przechodzi na 8 bitów, a edytor raz o tym mówi.


Jak radzimy sobie z nietypowymi plikami DNG?
DNG to otwarty format RAW, w którym zapisują zdjęcia m.in. telefony. Telefony zapisują w nim jednak rzeczy, których zwykły aparat nie zapisuje, i każda z nich wymagała osobnej pracy.
- DNG z kompresją JPEG XL. Tak zapisuje zdjęcia m.in. tryb Expert RAW w telefonach Samsung Galaxy. LibRaw sam takiego pliku nie otworzy, a jedyna gotowa droga prowadzi przez Adobe DNG SDK. Napisaliśmy własną: osobny dekoder libjxl 0.12.0 rozpakowuje kafelki obrazu, a nasz kod przepisuje plik na nieskompresowany DNG, który LibRaw już zna. Wynik porównaliśmy z narzędziem dng_validate od Adobe. Takie pliki otwieramy do 100 milionów pikseli, bo już taki plik zajmuje w LibRaw około 2,6 GB pamięci.
- Poprawki zapisane przez telefon. Pixel zapisuje w pliku DNG listę operacji, m.in. mapę wzmocnienia (GainMap), która rozjaśnia ciemniejsze rogi zdjęcia, i krzywe (MapPolynomial). Bez nich rogi wychodziły wyraźnie ciemniejsze niż w programach Adobe. Moduł, który je stosuje, napisaliśmy od zera, wyłącznie na podstawie publicznej specyfikacji DNG 1.7.1.0, przez osobną sesję, która nie widziała kodu Adobe. W Pixelu 7 Pro jasność rogów różni się teraz od wersji z Adobe najwyżej o 0,13 EV, a wcześniej różniła się o 0,6 EV.
- DNG z kompresją deflate i zmiennoprzecinkowy. Tak zapisuje Lightroom scalenia HDR i panoram. Do LibRaw dołączyliśmy niezmienioną bibliotekę zlib, a plikom bez zapisanego poziomu bieli edytor daje biel 1,0 ze specyfikacji DNG. Wcześniej taki 16-bitowy plik wychodził całkiem czarny.
Kolory z profili drukarni i pliki bez końcówki
Przy zwykłych formatach też trafiliśmy na pliki, z którymi przeglądarka sobie nie radzi. Nie przelicza ona profili kolorów w plikach TIFF, więc TIFF z Lightrooma w ProPhoto RGB albo TIFF w CMYK z profilem drukarni wychodziłby z wyblakłymi albo złymi kolorami. Profile przeliczamy więc sami. Obsługujemy profile macierzowe i tablicowe (mft1, mft2 i mAB), w tym FOGRA39, a wynik porównaliśmy z biblioteką lcms. JPG bez znacznika końca, na przykład ucięty przy przerwanym kopiowaniu z karty, dekoduje u nas libjpeg-turbo 3.2.0. Dzięki temu plik otwiera się tak samo w każdej przeglądarce, a ciemne zdjęcie nocne zachowuje prawdziwe kolory.

Jak liczymy podgląd na karcie graficznej?
Każdy ruch suwaka musi od razu zmieniać zdjęcie. Liczenie milionów pikseli w JavaScripcie trwałoby za długo, więc całą obróbkę robi karta graficzna przez WebGL2. Balans bieli, światło, mieszanie kolorów, gradację, winietę i ziarno liczy jeden program na karcie graficznej (shader) w jednym przejściu, na podglądzie w rozmiarze ekranu. Osobno liczy się tylko mapa poświaty dla kilku filtrów. Dlatego suwak reaguje płynnie nawet przy zdjęciu 100 Mpx.
Pełna rozdzielczość dekoduje się dopiero wtedy, gdy powiększasz zdjęcie albo je zapisujesz. Przy 100% i więcej edytor pokazuje prawdziwe piksele oryginału, pobierane kawałkami po 1024 px. Ostatnio oglądane kawałki zostają w pamięci, najwyżej 256 MB, więc powrót w to samo miejsce nie czeka na ponowne liczenie. Wyostrzanie i redukcja szumu działają na pikselach oryginału, dlatego najlepiej ocenisz je właśnie w powiększeniu.
Zapis używa tego samego shadera co podgląd, tylko liczy zdjęcie w kafelkach. Kafelki dobierają rozmiar do karty graficznej, więc zapis działa nawet na karcie z najmniejszą teksturą, jaką gwarantuje WebGL2 (2048 px). Automatyczny test porównuje podgląd z zapisanym plikiem i dopuszcza najwyżej 2 poziomy różnicy, a 3 tylko na ostrych krawędziach przy prostowaniu. To nasza odpowiedź na jedną z najczęstszych skarg z recenzji: co innego na ekranie, a co innego w pliku.

Jak działają przyciski Automatycznie bez AI?
Przycisk Automatycznie w sekcji Światło liczy statystyki zdjęcia i dobiera suwaki według reguł, które da się sprawdzić i powtórzyć. Ciemne zdjęcie rozjaśnia o połowę brakującej do średniej szarości ekspozycji, najwyżej o 1,5 EV, więc zdjęcie nocne zostaje nocne. Jasnego zdjęcia bez prześwietleń nie przyciemnia. Na koniec sprawdza, czy po jego ustawieniach nie przybyło przepalonych pikseli, a jeśli tak, cofa po kolei Biele, Ekspozycję i Światła.
Pierwsza wersja ciągnęła każde zdjęcie do 18% szarości. Pochmurny krajobraz po filtrze Automatycznie, który łączy oba przyciski, wychodził przez to szary, z jasnością 44,0 L* przy 63,3 w oryginale. Po poprawce ma 64,1. Przycisk Automatycznie w sekcji Kolor dobiera balans bieli z najjaśniejszych nieprzepalonych pikseli, ale gdy na zdjęciu przeważa jeden mocny kolor, na przykład brąz drewna albo pomarańcz zachodu słońca, zostawia większość tego koloru. Inaczej zachód słońca robiłby się szary.

Pipeta w sekcji Kolor działa po staremu: klikasz na zdjęciu coś, co w rzeczywistości jest białe albo szare, a edytor usuwa zafarb. Gdy w klikniętym miejscu jest za ciemno albo biel jest przepalona, edytor prosi o inny punkt, zamiast liczyć balans z danych, które nic nie mówią.

Sekcja Mieszanie kolorów zmienia barwę, nasycenie i jasność ośmiu pasm kolorów. Po włączeniu przełącznika Czarno-białe suwaki jasności decydują, jak jasno wyjdzie każdy kolor, tak jak kolorowe filtry zakładane kiedyś na obiektyw przy kliszy czarno-białej.

Sekcje Szczegóły, Gradacja kolorów i Efekty są na starcie zwinięte, żeby osoba, która chce tylko rozjaśnić zdjęcie, nie widziała trzydziestu suwaków naraz. Środek winiety przesuwasz, przeciągając punkt na zdjęciu albo strzałkami na klawiaturze.

Jak działa automatyczne prostowanie?
Przycisk Wyprostuj automatycznie szuka na zdjęciu horyzontu albo pionowych krawędzi budynków. Nie używamy do tego gotowej biblioteki, takiej jak OpenCV, która ważyłaby kilka megabajtów. Najpierw liczymy kierunek krawędzi w każdym miejscu zdjęcia z gradientów Scharra, które są równomierniejsze we wszystkich kierunkach niż popularny filtr Sobela. Potem transformata Hougha szuka linii, które leżą najwyżej 15° od poziomu albo pionu, i wybiera najmocniejszą. Gdy na zdjęciu nie ma wyraźnej linii, edytor nie zgaduje, tylko prosi, żeby ustawić kąt suwakiem.
Kadr zawsze leży w całości na zdjęciu, więc prostowanie nie zostawia w rogach pustych trójkątów.


Jak zbudowaliśmy 100 filtrów?
Każdy filtr najpierw dopasowuje światło i balans bieli do Twojego zdjęcia tymi samymi regułami co przyciski Automatycznie, a dopiero potem dodaje swój charakter. Dzięki temu Złota godzina wygląda podobnie na ciemnym i na jasnym zdjęciu. Miniatury filtrów liczą się na otwartym zdjęciu, a najechanie kursorem na filtr pokazuje go na dużym podglądzie, zanim cokolwiek się zmieni.
Część filtrów potrzebowała więcej niż suwaków:
- Tabele barw. Duotone, termowizja czy krzyżowe wywołanie zamieniają każdy kolor zdjęcia na inny. Nie używamy cudzych plików .cube: tabelę liczy kod edytora z przepisu zapisanego w liczbach, a ma ona 33 węzły na kanał w połowie precyzji, żeby w cieniach nie powstawały pasy.
- Poświata i halacja. Jasne miejsca zdjęcia edytor rozmywa i dodaje z powrotem, jak światło rozproszone we mgle. W filtrze Halacja zostaje sama czerwona obwódka wokół jasnych miejsc, jak na kliszy.
- Przesunięcie kanałów i nakładki. Filtry Y2K, Kaseta wideo i Glitch przesuwają kanały koloru, a Przeciek światła dodaje ciepłą smugę przy brzegu kadru. Wszystko liczy shader, bez gotowych obrazków.
Filtry stroiliśmy na pomiarach, a nie na oko. Harness renderuje 100 filtrów na 7 zdjęciach przy sile 100% i 150% i liczy dwie rzeczy. Pierwsza to różnica między filtrami w jednej kategorii w jednostkach ΔE2000: celem jest co najmniej 3, bo przy mniejszej różnicy dwa filtry dają prawie ten sam efekt pod inną nazwą. Po strojeniu poniżej tej granicy zostały tylko dwie pary, które zatwierdziliśmy świadomie. Druga to przepalenia. Gdy filtr dopycha jasne zdjęcie do bieli, edytor sam zmniejsza najpierw Biele, a potem Ekspozycję, i pokazuje zmienione liczby na suwakach. W ostatnim pomiarze żaden filtr nie przekroczył progu przepaleń w żadnym z 1400 sprawdzeń.


Jak edytujesz całą serię zdjęć naraz?
Po weselu albo wycieczce masz kilkadziesiąt zdjęć z jednej sesji. Poprawiasz jedno, zaznaczasz resztę i klikasz Nałóż ustawienia na zaznaczone. W oknie wybierasz grupy ustawień, a Kadr i obrót są domyślnie odznaczone, bo kadr pasuje tylko do zdjęć o tych samych proporcjach.
Sama kopia ustawień nie wystarcza, gdy słońce raz wyszło zza chmur, a raz się schowało. Opcja Wyrównaj jasność i balans bieli do tego zdjęcia porównuje każde zdjęcie ze wzorcem: jasność jako medianę w EV, bez przepaleń i głębokiej czerni, a kolor jako stosunki kanałów w półtonach. Najpierw sprawdza jednak, czy zdjęcia w ogóle pokazują podobną scenę. Liczy odcisk sceny z rozkładu jasności i z układu jasnych i ciemnych partii w siatce 4 × 4. Zdjęcie nieba obok zdjęcia lasu dostaje małą albo żadną korektę, więc błękit nie zamienia się w zieleń. Korekta ekspozycji ma granicę ±2 EV. Przy JPG i HEIC edytor bierze pod uwagę także różnicę czasu naświetlania, przysłony i ISO zapisanych przez aparat.

Każdy krok trafia do panelu Historia pod czytelną nazwą, na przykład Ekspozycja +0,40 albo Filtr: Krajobraz wyrazisty. Kolejne ruchy tego samego suwaka w ciągu 1,5 s łączą się w jeden krok, a kliknięcie dowolnego kroku przywraca zdjęcie do stanu z tamtej chwili.

Jak działa zapis?
Okno Zapisz zdjęcia ma cztery cele: Pełna jakość, Strona i e-mail (dłuższy bok 2048 px), Media społecznościowe (szerokość 1080 px) i Własne ustawienia. Pole Format domyślnie stoi na Jak oryginał, więc każde zdjęcie zapisuje się w swoim formacie, a RAW i HEIC jako JPG, bo tych formatów nie da się zapisać. Okno pokazuje wynik przed zapisem, na przykład Wynik: 8064 × 6048 px, JPG.
Każdy format zapisuje się inaczej. JPG i PNG zapisuje płótno przeglądarki, bo to najszybsze. WebP też, ale Safari tego nie umie, więc dostaje bibliotekę libwebp w osobnym wątku. AVIF, TIFF, BMP i GIF koduje osobny wątek, żeby strona się nie zacięła. Seria trafia do jednego pliku ZIP, a w pamięci jest naraz tylko jedno zdjęcie w pełnej rozdzielczości, więc nawet długa seria nie zapycha przeglądarki. Przycisk Przerwij zatrzymuje zapis w około 0,4 s, zanim przeglądarka cokolwiek pobierze.
iPhone i iPad nie pomieszczą dużego zdjęcia w jednym płótnie: w iOS 17 i starszych granica to 4096 × 4096 pikseli. Edytor składa więc zdjęcie z kafelków i sam koduje JPG oraz PNG, dzięki czemu także na telefonie zapisujesz w pełnej rozdzielczości. Na mocno obciążonym komputerze zapis sam zwalnia. W Chrome edytor korzysta przy tym z Compute Pressure API, które mówi, jak mocno pracuje procesor, a w innych przeglądarkach mierzy czas klatek na stronie. Okno o tym informuje, a przycisk Pełna moc przywraca pełne tempo.
Opcja Zachowaj dane aparatu (bez lokalizacji) przenosi do nowego pliku model aparatu, obiektyw, datę i ustawienia zdjęcia, zapisane w formacie, który każdy z formatów przewiduje: w JPG, PNG, WebP, AVIF i TIFF. Lokalizację GPS, numery seryjne aparatu i obiektywu oraz dane producenta (MakerNote) zawsze usuwamy. BMP i GIF nie mają miejsca na takie dane, o czym okno przypomina.


Jak pilnujemy, żeby praca nie zginęła?
Każda zmiana zapisuje się sama w przeglądarce, razem z kopią oryginału. Oryginały i ustawienia trzymamy w IndexedDB, bo jedna transakcja obejmuje tam i plik, i ustawienia, a zapis działa w każdej przeglądarce. Po powrocie edytor pokazuje Wróć do pracy z liczbą zdjęć i datą ostatniej zmiany. Gdy ostatni zapis jest uszkodzony, wraca wersja sprzed chwili, a gdy przeglądarka w trakcie pracy wyczyści dane strony, edytor zakłada bazę od nowa i zapisuje otwarte zdjęcia jeszcze raz.
Safari usuwa dane strony po 7 dniach korzystania z przeglądarki bez wizyty na niej, więc przy pierwszym zdjęciu w Safari edytor raz o tym uprzedza. Na taki wypadek jest przycisk Pobierz ustawienia, który zapisuje ustawienia i historię wszystkich otwartych zdjęć w małym pliku JSON. Wczytaj ustawienia przywraca je zdjęciom o tej samej nazwie i wielkości pliku, także na innym komputerze.

Dwie karty z edytorem
Gdy otworzysz Helios w dwóch kartach, obie mogłyby zapisywać pracę naraz i nadpisywać sobie zmiany. Dlatego edytuje zawsze jedna karta, a druga pokazuje komunikat z przyciskiem Pracuj w tej karcie. Pilnuje tego Web Locks API, a karty rozmawiają ze sobą przez BroadcastChannel. Przejęcie trwa zwykle ułamek sekundy, a nowa karta dostaje najnowszą zmianę drugiej, nawet w trakcie przeciągania suwaka. Safari od 15.0 do 15.3 nie ma żadnego z tych mechanizmów, więc tam działa dzierżawa zapisana w localStorage, którą karta co chwilę odnawia.

Jak Helios radzi sobie z dziwnymi plikami?
Zakładamy, że do edytora trafi wszystko. Format rozpoznajemy po zawartości pliku, a nie po rozszerzeniu, więc JPG zapisany jako .png albo PNG bez rozszerzenia otwiera się normalnie. Pusty plik, faktura PDF z rozszerzeniem .jpg albo plik ucięty w połowie dostają jasny komunikat, a reszta serii otwiera się dalej. Granice też mają własne komunikaty: zdjęcie może mieć najwyżej 268 milionów pikseli, a plik najwyżej 2 GB. Przypadki brzegowe spisujemy w osobnym dokumencie i każdy dostaje test.
Skróty klawiszowe pokazuje okno pod klawiszem ? albo pod ikoną klawiatury na górnym pasku. W recenzjach innych programów często wracała skarga, że skróty istnieją, ale nikt o nich nie wie.

Jak testujemy Helios?
Helios ma ponad 80 plików testów jednostkowych w Vitest z blisko 900 przypadkami oraz ponad 30 plików scenariuszy w Playwright, które otwierają edytor w Chromium, Firefoksie i WebKicie. Testy sprawdzają m.in. zgodność podglądu z plikiem, przejmowanie edycji między kartami, przerwany zapis, pliki uszkodzone i przypadki brzegowe pól liczbowych. Pole przy suwaku przyjmuje przecinek albo kropkę, minus typograficzny i cyfry arabskie, perskie, tajskie i japońskie, bo interfejs jest w ośmiu językach.
Dekodowanie sprawdzamy na prawdziwych plikach z otwartej bazy raw.pixls.us na licencji CC0. Lista aparatów i telefonów, których pliki otworzyliśmy, stoi na stronie Heliosa, a są na niej m.in. Canon EOS 6D, Nikon Z 6, Fujifilm GFX100 II, iPhone 12 Pro i Samsung Galaxy S23 Ultra. Szybkość otwierania mierzymy skryptem, który dla każdego pliku zapisuje czas pierwszego obrazu i czas do edycji, więc każda zmiana w dekoderze ma liczby przed i po.
Mówimy też wprost, czego nie sprawdziliśmy. Testy Safari idą w WebKicie z Playwrighta i w emulacji granic iOS, a to nie zastępuje prawdziwego iPhone'a. Firefox dekoduje pliki RAW kilka razy wolniej niż Chrome i Edge. Tej przyczyny nie usuwamy, ale edytor mówi o tym przy pierwszym takim pliku.
Telefon i reklamy
Helios działa też na telefonie, a suwaki obsługujesz dotykiem. Reklamy edytor dobiera do wielkości okna: na komputerze w bocznej kolumnie stoi baner 160 × 600 albo do trzech prostokątów 300 × 250, a na telefonie pasek 320 × 50 na samym dole. Reklama nigdy nie jest ucięta, nie zasłania zdjęcia ani przycisków, a test sprawdza, że zapis działa także przy zablokowanych reklamach.

Co dalej z Heliosem?
Helios poprawia dziś całe zdjęcie naraz. Na liście kolejnych etapów są:
- korekty lokalne: najpierw gradient liniowy, który przyciemni samo niebo, a potem punkt korekty, oba bez AI,
- krzywa tonalna,
- przegląd serii z odrzucaniem zdjęć z klawiatury i wybór całego folderu zamiast zaznaczania plików,
- łatka i klon z ręcznie wybranym źródłem do usuwania drobnych rzeczy ze zdjęcia,
- osobne odszumianie barwy, które już zmierzyliśmy na prawdziwych plikach RAW,
- profil kolorów zapisany w plikach DNG z telefonów, dzięki któremu zdjęcia z Pixela wyjdą mniej płaskie,
- układ zaprojektowany od początku pod telefon.
Pomysły i błędy zgłosisz przez formularz pod treścią na stronie Heliosa. Jeśli plik z Twojego aparatu nie otwiera się poprawnie, napisz, z jakiego aparatu pochodzi. O tym, jak powstała cała platforma, przeczytasz w case study Arteon Tools.
Czy zbudujemy podobne narzędzie dla Twojej firmy?
Helios pokazuje, że w przeglądarce da się dziś zrobić program, który jeszcze niedawno wymagał instalacji: z WebAssembly, obliczeniami na karcie graficznej i pracą zapisaną na urządzeniu użytkownika. Konfigurator produktu z podglądem, edytor zdjęć dla klientów sklepu albo narzędzie, które przetwarza pliki bez wysyłania ich na serwer, możemy zbudować w tej samej technologii. Jeśli masz taki pomysł, napisz do nas.
Najczęstsze pytania dotyczące realizacji
Czy Helios jest darmowy?
Tak. Edycja i zapis są darmowe, bez konta, bez subskrypcji i bez limitu zdjęć. Rozwój Heliosa i pozostałych narzędzi utrzymują reklamy Google AdSense, które stoją w bocznej kolumnie edytora i nigdy nie blokują zapisu.
Czy zdjęcia trafiają na serwer?
Nie. Helios otwiera, edytuje i zapisuje zdjęcia w Twojej przeglądarce. Dekoder RAW, obróbka na karcie graficznej i kodery formatów działają na Twoim urządzeniu, a kopia pracy zapisuje się w danych strony w przeglądarce.
Jakie pliki RAW otworzy Helios?
Helios otwiera pliki RAW przez bibliotekę LibRaw 0.22.2, m.in. CR3 i CR2 z Canona, NEF z Nikona, ARW z Sony, RAF z Fujifilm (także X-Trans), RW2 z Panasonica i DNG z telefonów, w tym DNG z kompresją JPEG XL do 100 milionów pikseli.
Dlaczego Helios nie używa AI?
Bo chcemy, żeby ten sam przycisk dawał za każdym razem ten sam wynik, działał bez serwera i bez kredytów. Przyciski Automatycznie, wyrównanie serii, automatyczne prostowanie i filtry liczą wynik klasycznymi metodami ze statystyk zdjęcia.
W jakich przeglądarkach działa Helios?
W Chrome, Edge, Firefoksie i Safari od wersji 15.0, na komputerze, telefonie i tablecie. Przeglądarka musi obsługiwać WebGL2. Pliki HEIC otworzysz w Safari od 16.4 oraz w Chrome i Edge, gdy system ma dekoder HEVC, a Firefox otwiera pliki RAW kilka razy wolniej niż Chrome i Edge.
Co się stanie, gdy zamknę kartę w trakcie edycji?
Nic nie przepadnie. Każda zmiana zapisuje się w przeglądarce, a po powrocie edytor pokaże przycisk Wróć do pracy. Dla pewności możesz pobrać plik ustawień przyciskiem Pobierz ustawienia, który przywrócisz także na innym komputerze.
Czy Helios zastąpi Lightrooma?
Przy poprawianiu światła, koloru, kadru i całych serii zdjęć tak. Helios nie ma jednak jeszcze korekt lokalnych, pędzla, warstw ani usuwania przedmiotów ze zdjęcia, a biblioteki zdjęć nie prowadzi, bo pliki zostają u Ciebie na dysku.
Czy możecie zbudować podobny program dla mojej firmy?
Tak. Edytory, konfiguratory i narzędzia, które przetwarzają pliki w przeglądarce, budujemy w Next.js, React, TypeScript i WebAssembly, tak jak Helios. Napisz do nas przez stronę kontaktu i opisz, co narzędzie ma robić.
Sprawdź najnowsze realizacje

Otwórz Helios i popraw swoje zdjęcia
Wrzuć zdjęcie z telefonu albo plik RAW z aparatu i sprawdź Heliosa w działaniu. Pliki zostają na Twoim komputerze.









