PHP jpg-ből webp-be hibássan konvertál

Egyik tárhely szerveren valamiért hibásan konvertálja a jpg-t webp-be. Valaki tálalakozott már hasonló hibával?

Próbáltam hasonló környezetet kialakítani másik virtuális szerveren is de nem ott nem jött elő ez a hiba.

Amit eddig megállapítottam:

  • a problémás szerveren generált webp-t a chrome rosszul jeleníti meg, viszont az FF jól
  • webp kép valószínűleg hibás, mivel a gimp sem volt képes betölteni
  • A php-gd-libwebp hármas generálja  képet, valahol itt lehet a probléma
  • A teszteket php7.x -a paranccsal csináltam, hogy ne avatkozzon bele más folyamat.
  • A probléma független attól, hogy  7.0-ás vagy 7.4-es phpt használok
  • GD verzió mindenhol 2.3

Minta kód:

user@server:~/www/dev/uploads/webp/temp$ php7.0 -a
Interactive mode enabled

php > $img = imagecreatefromjpeg('test.jpg');
php > imagewebp($img,'test.webp',80)

 

Teszt környezetek:

Problémás szerver

ubuntu 16.04.7 LTS,
php 7.0.33-37+ubuntu16.04.1+deb.sury.org+1
php 7.4.12-3+ubuntu16.04.1+deb.sury.org+1
libwebp6 0.6.0-4+ubuntu16.04.1+deb.sury.org+1

 

saját környezet, jól generálta le a képet

Ubuntu 18.04.4 LTS,
php Version: 7.0.33-37+ubuntu18.04.1+deb.sury.org+1,
php 7.4.12-3+ubuntu18.04.1+deb.sury.org+1
libwebp6 0.6.1-2

 

Hasonló környezet, jól generálta le a képet

ubuntu 16.04.7 LTS,
php 7.0.33-37+ubuntu16.04.1+deb.sury.org+1
php 7.4.12-3+ubuntu16.04.1+deb.sury.org+1
libwebp6 0.6.0-4+ubuntu16.04.1+deb.sury.org+1

Minta fájlok

https://drive.google.com/file/d/1hj4XbZQYkKkc4PjHFI5tQ_0mhx3H_jqq/view?usp=sharing

Hozzászólások

Laikus kérdés, de nem túl rövid a webp? Azaz nem a szerver vágja le a végét mondjuk 64k-nal? Belenezve mi rossz benne, fejléc jó, adatok nem? Minden képpel csinálja a hibát vagy csak néhánnyal? Lehet bizonyos bitmelyseget / méretet nem kezel valami helyi beállítás miatt. 

  • Laikus kérdés, de nem túl rövid a webp?
    • Kis méretű webp-ket látszólag jól jeleníti meg
  • Azaz nem a szerver vágja le a végét mondjuk 64k-nal?
    • Nem, sőt a jól generált még kisebb is 5k-val
    • Szervernek nem is nagyon van rá hatása. PHP-val, amikor legeneráltam, áttöltöm ftpn a saját gépemre, majd beledobom böngészőbe.
  • Belenezve mi rossz benne, fejléc jó, adatok nem?
    • Hexaeditorral megnézem, de nem sok mindent láttam. Tudsz rá valami jó toolt?
  • Minden képpel csinálja a hibát vagy csak néhánnyal?
    • jpg, png összessel
  • Lehet bizonyos bitmelyseget / méretet nem kezel valami helyi beállítás miatt.
    • Van tipped arra, hogy ezek a beállításokat merre keressem?

nincs ötlet, de mondjuk az érdekes, hogy a hibásan generáltat az FF jól jeleníti meg.. minden más meg nem :/ Az úgy elég fura.

Vírus? Mondjuk szándékosan invalid képadatot csinál, ami valami sebezhetőséget kihasználna? Elrugaszkodott, de végülis bármi lehet.

Félig ez megoldja:

if (filesize('test_img.webp') % 2 == 1) {
    file_put_contents('test_img.webp', "\0", FILE_APPEND);
}

De átlátszóság hibáját nem orvosolja.

fel tudod vhova tolteni ugyan azon webpnek a jol es rosszul legeneralt valtozatat?

lehetoleg a 'Problemas szerver' es 'Hasonló környezet, jól generálta le a képet' kornyezetekbol 1-1et, kivancsi lennek egy binary diffre a ketto kozott...

- fizikailag minden ok a géppel? memória?
- ha a php.ini-ket diff-eled, mik a különbségek?

A képet a böngészőnek adod vissza generálás után vagy lemented?
Előbbi esetben ob_clean() -t tegyél közvetlenül elé és mögé meg exit() -et.
 

  • fizikailag minden ok a géppel? memória?
    • Szerintem igen, mert akkor máshol is előjött volna ez a probléma, sokat van használva az említett szerver.
  • ha a php.ini-ket diff-eled, mik a különbségek?
    • Ugyan azokat az ini-ket állítottam be. memcache-t nem tudtam még egy szintre húzni de a többit ugyan azzal a beállítással futtattam, illetve pár pdo-t nem raktam fel. Szerintem ezek nem is befolyásolják
  • A képet a böngészőnek adod vissza generálás után vagy lemented?

Szervernek nem is nagyon van rá hatása. PHP-val, amikor legeneráltam, áttöltöm ftpn a saját gépemre, majd beledobom böngészőbe.

A fenti SO-n levo hiba az biztos, hogy letezik, mert hibas a paddingja es a nullbyte hozzaadasa megjavitja.

dwebp utilitybol:

File generalt.webp can be decoded (dimensions: 1280 x 1179  (with alpha). Format: lossy).

File hibas_generalas_nullfix.webp can be decoded (dimensions: 1280 x 1179 . Format: lossy).

Tehat az atlatszosag azert nem mukodik, mert nem is tartalmaz alphat.

 

En megneznem, hogy biztosan azokat a libeket tolti-e be, amit irsz... pl:

strace php convert.php 2>&1 | grep -i webp

pl:

openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libwebp.so.6", O_RDONLY|O_CLOEXEC) = 3

"Some versions of libgd forget to add a zero padding at the end of odd-sized webp files"

"For each VP8 frame written by imagewebp(), we need to check if the frame length is even."

És tényleg. A végére raktam egy \0-t és működik.

Egyébként érdekes, hogy az egyik VP8, a másik nem:

$ file *.webp
generalt.webp:        RIFF (little-endian) data, Web/P image
hibas_generalas.webp: RIFF (little-endian) data, Web/P image, VP8 encoding, 1280x1179, Scaling: [none]x[none], YUV color, decoders should clamp

A generalt.webp az 3 RIFF chunkot tartalmaz: VP8X, ALPH, VP8 (ez VP8 extended, csak tarol kulon egy alpha imagedatat es magat a kepet)

A hibas_generalas.webp az 1 RIFF chuckot tartalmaz: VP8

A file utility csak az elso RIFF chunkot nezi es nem ismeri rendesen a VP8X-et, igy nem jon ra, hogy mi az, viszont a sima VP8-ra igen.

Sources / tools:

https://ide.kaitai.io/ -> formats/common/riff.ksy

https://developers.google.com/speed/webp/docs/riff_container#extended_f…

Pár gondolat, ami nem lesz segítség a topiknyitónak, de kikívánkozik: minek átkonvertálni a jpg-et webp-be? Tudom, a webp most még új, meg buzzword, de egyrészt nincs elterjedve, meg jpg-ből konvertálva nincs előnye. Ha veszteségmentes webp-be konvertál valaki, akkor a fájlméret nő meg, de a minőség változatlan marad, ha meg veszteségesbe, akkor lossy2lossy konvertálással tovább romlik a minőség. Plusz ha valaki annyira konvertálási fetisiszta, akkor sem PHP-val javallott ezt csinálni, hanem linuxon imagemagick csomagból a convert paranccsal. Cipőt a cipőboltból alapon.

The world runs on Excel spreadsheets. (Dylan Beattie)

- egy weboldalnál, ahol sok-sok kép van, szerintem 20-30%-ot is meg lehet takarítani, úgy hogy nem romlik a képek minősége
- jpg-ből konvertálva is van előnye főleg mikor az eredeti feltöltött 5Mpixeles képet fullhd-ba konvertálod, plusz még további méretekbe (thumbnail, cover, stb.)
- a PHP alatt használható imagemagick a GD helyett - http://image.intervention.io/getting_started/configuration
- DE még én sem "merem" használni, mert valóban nem biztos hogy minden látogató böngészője meg tudja emészteni - https://caniuse.com/?search=webp

Tudom, a webp most még új, meg buzzword, de egyrészt nincs elterjedve

tudom, mi profitorientált helyekre dolgozunk. de nálunk az újítás nem ördögtől való. mi elemezzük pl a látogatók/nálunk költők részét. és mi őket akarjuk kiszolgálni

"miért nem árul ez a luxusóra bolt casiot, pedig az olyan elterjedt?" oké. de ennek a boltnak a vevői nem kíváncsiak rá. és 2%-ért nem ruháznak be. meg lehet ezt is érteni. van olyan igény is, hogy a legújabbra/legkeresőképesebbre optimalizálunk. ennyi

4 és fél éve csak vim-et használok. elsősorban azért, mert még nem jöttem rá, hogy kell kilépni belőle.

Félreértetek, nekem nincs bajom a webp-vel. Általában támogatni szoktam az újabb, jobb formátumok elterjedését, így van ez a webp, heic, avif formátumokkal is. De én böngészőben nem feltétlen erőltetném, főleg nem PHP-ből tömegesen konvertálva. Ahhoz még nem elég kipróbált, nem elég elterjedt technológia.

The world runs on Excel spreadsheets. (Dylan Beattie)

Sajnos egyenlőre nem derült ki hogy mi lehet baja, sajnos több időt nem is tudok rászánni.

A megoldás a cwebp lett exec segítségével. Jól működik, talán még gyorsabban is.

exec("cwebp -q 80 ".escapeshellarg($filepath)." -o ".escapeshellarg($filepath_webp));

+1 az imagick-re, hatha az megy. Ugy hordozhato lesz a kod, imagick altalaban mindenhol telepitve van.

Exec-nel 1-el jobb megoldas a post-processing, azaz cron-bol hivsz meg idokozonkent egy scriptet es az gyartja le neked ezeket a fileokat. De ez hatranyokat is hozhat magaval, attol fugg mit csinal a frontend.

Exec es baratait meg jobb tiltani.