2012-11-30 10 views
17

Mam aplikację do udostępniania zdjęć PHP, w której obrazy przesłane przez użytkownika są zmieniane na różne formaty kciuków za pomocą ImageMagick.Jak usunąć plik exif z JPG bez utraty jakości obrazu?

Jak pozornie „inteligentny” sposób na zaoszczędzenie na rozmiar pliku, mam stripping informacje EXIF ​​z tymi kciukami następująco:

$imagick = new Imagick($image); 
$imagick->stripImage(); 
$imagick->writeImage($image); 

To działa. Usuwa informacje EXIF, gdzie kciuki 30KB zapisują 12KB i stają się 18KB. Znacząca oszczędność przy pokazywaniu wielu takich kciuków na jednej stronie.

Problem polega jednak na tym, że działa zbyt dobrze. Uzyskane obrazy wydają się tracić wiele informacji o kolorze i wyglądają "płasko" w porównaniu z ich nierozkładanymi wersjami.

podstawie moich dotychczasowych badań, moja teoria jest taka, że ​​jeden lub oba z następujących warunków:

  • Imagick wyrzuca podstawowe informacje o profilu kolorów jako część procesu odpędzania
  • Imagick kompresowane obraz po zapisaniu, utracie jakości

Bez względu na przyczynę problemu, szukam sposobu na usunięcie informacji EXIF ​​w taki sposób, aby nie wpłynęło to na jakość obrazu lub kolor.

Czy to możliwe?

Aktualizacja:

podstawie odpowiedzi Gerald Schneider, próbowałem egzekwowania ustawienie jakości do 100% przed "stripping" Obraz:

$imagick = new Imagick($image); 
$imagick->setCompression(imagick::COMPRESSION_JPEG); 
$imagick->setCompressionQuality(100); 
$imagick->stripImage(); 
$imagick->writeImage($image); 

Niestety, problem pozostaje. Poniżej znajduje się przykładowy wynik, w którym pomimo ustawienia jakości na 100%, obrazy są nadal spłaszczone.

enter image description here

+2

Jakoś wątpię, że usunięcie EXIF ​​zmniejsza rozmiar pliku o tyle. Wydaje mi się, że zmniejszenie rozmiaru pliku wynika raczej z rekompresji, może z niższej jakości niż poprzednio. Czy próbowałeś użyć 'getCompressionQuality()' i 'setCompressionQuality()'? –

+0

@GeraldSchneider to zależy. Widziałem pliki z dosłownie setkami kilobajtów (prawie pół miliona w ekstremalnych przypadkach) danych EXIF. Rozbiórka obrazów EXIF ​​to zawsze dobry pomysł. – mingos

+0

To może być prawdą w przypadku obrazu prosto z aparatu, ale z wygenerowanej miniatury? –

Odpowiedz

22

Rozważ utrzymanie profilu ICC (co powoduje, bogatsze kolory) usuwając wszystkie pozostałe dane EXIF:

  1. wyodrębnić profil ICC
  2. danych i obrazu
  3. Strip EXIF ​​profil
  4. dodać profil ICC powrotem

W PHP + Imagick:

$profiles = $img->getImageProfiles("icc", true); 

$img->stripImage(); 

if(!empty($profiles)) 
    $img->profileImage("icc", $profiles['icc']); 

(Ważna uwaga: użycie ImageMagick 3.1.0 beta, wynik jaki uzyskałem z getImageProfiles() był nieco inny niż documentation. Radziłbym zabawy z parametrami aż pojawi się tablicę asocjacyjną z rzeczywistym profilem (ów))

Dla wiersza polecenia ImageMagick.

convert image.jpg profile.icm 
convert image.jpg -strip -profile profile.icm output.jpg 

Obrazy dostanie rekompresji oczywiście jeśli używasz ImageMagick , ale przynajmniej kolory pozostają nienaruszone.

Mam nadzieję, że to pomoże.

+1

Dzięki, Robbert. Wypróbowałem kilka innych technik, ale to była jedyna, która dała mi wyniki, których szukałem. Pracuję z ImageMagick z linii poleceń, więc musiałem trochę przetłumaczyć: 1) Zapisz profil do pliku 'convert image.jpg profile.icm' 2) Usuń profil z obrazu, a następnie ponownie zastosuj z pliku' convert image.jpg -auto-orient -strip -profile profile.icm output.jpg' –

+0

Cieszę się, że mogę pomóc, Chad. Dzięki za dostarczenie alternatywnej linii poleceń - dodałem twój kod do odpowiedzi. – Robbert

+0

Cool, just fyi, -auto-orient do ustawiania zdjęć z danymi rotacji exif i nie jest konieczne, aby polecenie działało. Chciałem to usunąć z komentarza, ale moje okno edycji wygasło! –

1

Po dokonaniu zmian w podobnych typów MIME w nagłówkach plików, które były niewłaściwie przechowywane, sugeruję sprawdzić długość danych EXIF ​​za pomocą standardowych narzędzi, a następnie „zero” dane ręcznie za pomocą funkcje ciągów wielobajtowych.

EXIF ​​może mieć maksymalnie 64 KB w pliku JPEG, jednak nie jestem pozytywny, jeśli jest to tylko 64 KB, więc zacznę od tego.