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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

- 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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.