Autor Zpráva
Galathas
Profil *
Zdravím PHP komunitu!

Chtěl bych se zeptat zkušenějších, zdali je nějaká možnost (jakákoliv,kromě zvýšení přídělu paměti na hostingu) jak obejít "Allowed memory exhausted" chybu při volání imagecreatefromjpeg v PHP ? Je nějaké jiné řešení jak zmenšit velký jpeg v PHP než volání této funkce při procesu zmenšení obr. ?

pozn. - nemám možnost využít "command-line" programy (djpeg,pnmscale,magickwand) protože jde o hostováné stránky, takže nemůžu nic instalovat, a už vůbec nemůžu využít ini_set() trik z php.net a nastavit si vetší allowed_memmory_limit.

Moc prosím, kdyby jste někdo věděl o nějakém řešení jiném , něž že si má klient zmenšit své 3MB obrázky z dovolené sám :-) před uploadem, dejte prosím vědět.

Předem děkuju za pomoc a tipy.Přeji pěkný den a php zdar :-)
Dmagician
Profil
Sice nerad to hovorim, ale tiez som ten problem este nevyriesil. ;-)

Da sa vsak aspon zistit kolko bude obrazok zaberat a ak bude prilis velky tak vyhodit hlasku ze obrazok je prilis velky

napr tu.

http://sk2.php.net/manual/sk/function.imagecreatefromjpeg.php#56032


Dalej v diskusii sa riesi aj zvysovanie limitu, ale tam treba mat povolene ho zvysovat. (coz nemas)
Galathas
Profil *
Zdravim Dmagician ! :-)

a děkuju moc za tip, podobně se s tim vypořádali na php.net, ale ja potřebuju povolit upload libovolného obrázku, který si klient přeje, a zmenšit si ho až na serveru, nemůžu klientovi po uploadu vypsat hlášku, že čekal na nahrání zbytečně , protože jeho obrázek je příliš velký... :-)

- přemýšlel jsem, že se mrknu na metody jak se jpeg zmenšuje (down-sampling), že bych se pokusil udělat v php něco podobného bez použití imagecreatefromjpeg(), ale poté co jsem zjistil, jaké funkce, a matematika za tím stojí, mám pocit, že na tohle by knihovny z php nestačili ... :-) a hlavně počítám, že bych narazil na memory_limit ještě dříve, než samotná imagecreatefromjpeg() :-)

každopádně dík moc za tip !
Dmagician
Profil
heh.. ved prave.. to iste napadlo aj mna, ale pracovat na subore cez PHP by bolo velmi pomale. Aj keby si zvladol format suboru a vedel s nim manipulovat.
Galathas
Profil *
...manipulovat s jpeg souborem není až zas takový problém (viz např. http://www.obrador.com/essentialjpeg/headerinfo.htm ), dělal jsem to kdysi s kamarádem, když jsme překládali jednu hru a potřebovali jsem vyexportovat obrázky z jednoho velkého dat souboru, stačí si najít ve změti dat header a endheader a to co je mezi nim vyexportovat a uložit do jpg souboru a voila, funguje to :-), ale souhlasim s tebou, že by prace se souborem v php byla velmi pomala ! škoda :-)

- nicméně říkal jsem si, že by možná stálo za pokus přečíst jpg do pole řádků ( "šířka x výška" ) bez headeru a footeru a při 2x zmenšení (800x600 -> 400x300) prostě vynechat každý druhý řádek (resp. sloupec) a výsledek uložit do jpeg s aktualizovanou hlavičkou. To by nemuselo být až tak náročné, ovšem kvalita takového jpegu by byla asi hrozná :-) především proto, že by se neprováděl sampling tj. nevzala by se matrice např. 8x8b a neinterpolovala by se barva bodu uprostřed, tak jak se to dělá standartně v programech... prostě by se body smazali :-)) to by byl asi pěknej humus...
Dmagician
Profil
Az na to, ze najst zaciatok a koniec hlavicky jpg v nejakom binarnom subore nie je manipulacia s jpg samotnym. Mal som na mysli prave citanie suboru a manipulaciu s nim, uvazujem ako to ze to este nikto predtym neskusal. Uplne by stacilo primitivne resize na "stravitelnu velkost" a potom to dorazit resamplingom.
Galathas
Profil *
...Jasne, rozumim, presne tak jsem to myslel, ale abys mohl cist samotny data jpegu, musis nejprve precist SOI+header a EOI a odstranit je, pak nacist binar, data mezi (to je samotny jpeg) a provest RGB - > Y,Cb,Cr precist z headeru hodnotu x(horizontal) a y(vertical), vzit nelepe 8x8 blok a provest DCT (kosinovska transformace - tak jsou vetsinou jpeg komprimovany), toto provest pres vsechny bloky, nastavit novou hodnotu x,y,velikost v headeru a ulozit transf. bin data pres dct nebo jinou komprimacni metodu (definovanou v iso standartu jpeg) a vysledny bin data ulozit mezi novou hlavicku a paticku (EOI) a cely to ulozit jako novy jpeg... :-) takze docela sranda :-) a navic se obavam, ze ackoliv jsem nevidel zdrojak k imagecreatefromjpeg, tak ze tahle funkce bude mit stejny pristup k veci, a tudiz jestlize selhava na velkych souborech ona, tak by takovato postup selhal na pozadavcich na pamet taky. A to predevsim proto, ze zkomprimovany jpeg musis pred upravou nejprve dekomprimovat (viz.vyse) a tudiz potrebujes dekomprimovany jpeg nekam ulozit, a nejrychlejsi moznost z hlediska vykonu je logicky pamet, takze pak skoncis stejne jako ICFJpeg funkce...alternativne by mozna bylo mozne ulozit dekomprimovany jpeg do souboru a pracovat s nim po castech, ale neumim si predstavit jak rychla by tahle operace byla, pravdepodobne moc ne, a to neuvazujem jak by zatezovala nadmerne server na kterem by skript bezel - vezm-li v uvahu 100x2MB jpeg nevim,nevim jestli by se vubec uzivatel v rozumne dobe dockal...:-)

...nene, chce to jit na to jinak, obejit tuhle dekompriaci i za cenu horsiho vzhledu, neb kdo potrebuje mit jako nahled na netu obrazky v tiskove kvalite ?? Na netu je mam pro to, aby lidi mohli rychle shlidnout obrazky z akci, ne proto, aby si je stahovali a tiskli na 1mx1m velky platno :-)) ne ?

...Dekuju ze nad tim taky premyslis a dekuju za podnety. Kdyby te cokoliv napadlo, dej vedet. Dik Peknou nedeli !
Galathas
Profil *
...Kdyby ses chtel mrknout na supr dokument o kodovani/dekodovani jpegu podle standartu, mrkni na
http://www.wotsit.org/download.asp?f=jpeg Doporucuju kazdemu, kdo si mysli ze zobrazit jpeg ze sveho fotacku je sranda:-))
Galathas
Profil *
...pardon, chlapek ma nastaven refferer check, takze mrknete sem : http://www.wotsit.org/search.asp?page=5&s=graphics a hledejte pod kategorii jpeg :-)
Dmagician
Profil
Myslim ze nic jednoduche a primitivne bohuzial nevymyslime. Musime pockat kym to za nas niekto vyriesi, alebo poziadat servery o zvysenie limitov ;-) (obidve moznosti viac menej nerealne)
Galathas
Profil *
...a co jit na to od lesa :-) ? Jak jsem zistil, tak na mem hostingu mi script (resp. imagecreatefromjpeg) jede az do 400kb/soubor. Takze pokud ho nechci zmensit cely, co ho pri zachovani wxh podilu rozdelit na mensi 400kb - 4x100kb tem vytvorit novou hlavicku, pridat paticku, zapamatovat si info, kde jak jsou vuci sobe polozeny a poslat je do for () loop. tam je resizovat standartne imagecreatetruecolor(),imagecreatefromjpeg(),imagecopyresampled() a imagejpeg() - a pak tyhle zmenseny jpegy napozicovat vedle sebe a spojit do jednoho jpegu...

Zkusim to a dam vedet. :-)
Dmagician
Profil
No neviem neviem ci nezarve na memory Allowed memory exhausted hned ako otvoris ten jpg na "kopirovanie" ale napad je to dobry. Som zvedavy.
Galathas
Profil *
...to problem neni, protoze otevru ten obr. jako bin soubor a vykopiruju binarni bloky, imageCFJ zarve pravdepodobne proto, ze ten kdo to programoval dekomprimuje jpeg v cyklu 8x8 bloky najednou misto aby je ukladal a nacital postupne... ale zkousel jsem to a nejde to kvuli 1 veci:

1] kazdy jpeg ma totiz konkretni tyv. Huffmanovu tabulku cisel, podle ktery se pak soubor pred zobrazenim dekoduje ( resp. nejprve se dekoduje pres tuhle tabulku, a teprv pote se spusti standartni DCT a prevod na RGB), tahle tabulka se vytvari pri vytvoreni jpegu a bohuzel nestaci jen vertikalne rozdelit obr. samostatne ho zpracovat a pak je spojit za sebe, protoze ta druha cast nebude dekodovana pomoci Huffmanovi tabulky prvniho obrazku - tzn. druhy obrazek se nezobrazi...takze by se musel prekodovat cely spojeny obr. znovu s novou H tabulkou, coz by ovsem znamenalo otevrit puvodni soubor pomoci imageCFJ funkce a to by skoncilo chybou, takze tohle neni reseni :-))

Muze mi nekdo rict proc je ten format tak komplikovanej ?? :-))

No nic. Myslim ze nam zbyva jen cekat na optimalizaci imagecreatefromjpeg() od tvurcu :-)) a nebo podplatit adminy na hostingu, aby nam pridelili 32MB++ pameti :-)) Pekny den.
Dmagician
Profil
Heheh ;-) Esteby bolo zaujimave keby sa nejak dal objekt obrazku zobrazeny v browseri (a trebars pastnuty do wysiwyg editora ;-) uploadnut v aktualne zobrazenej velkosti ;-))) Nejako sa proste dostat k browserovym "screen datam" ;-)) Aalebo nejako pracovat priamo s "clipboardovymi" datami (ale to su az moc divoke napady.. nepocul som ze by na to IE nieco malo spravene)
anode
Profil
Zdravím,
musíš být opravdu zoufalý chtít něco takového:
"script (resp. imagecreatefromjpeg) jede az do 400kb/soubor"
"3MB obrázky z dovolené"
'nemám možnost využít "command-line" programy'

Jiné řešení než přechod na slušnější hosting není.
Jenom pár poznámek:
1) "čekat na optimalizaci imagecreatefromjpeg()" je docela zbytečné - vždyť vytváří v paměti bitmapu ze zvoleného JPEG obrázku, méně paměti prostě z principu brát nemůže
2) 'pracovat priamo s "clipboardovymi" datami', no to snad né! Clipboard přece plně přísluší uživateli, k tomu se webová stránka vůbec nemá dostat.
Dmagician
Profil
anode: a aky bol ucel tvojho prispevku? Frflat a flejmovat? ;))

Takze hovoris slusnejsi hosting? Neviem ktory virtualny hosting ti da moznost ho vytazit tak aby si ostatnych uzivatelov obmedzoval. Ja vidim jedinu moznost v "housingu" vlastneho servera.

1) suhlasim iba ciastocne, moze niekto vymysliet nejaky poorman's imagecreatefromjpg
2) "no to snad né? " - prosímťa načo tá hystéria? ;-) Co ked uzivatel chce aby bola operacia vykonana/povolena. Vsimol si si co som pisal? "nepocul som ze by IE malo nieco spravene". Nepredpokladam ze by nieco take robili ine prehliadace, ale ako poznam MS, je schopny kvoli inovacii obratit bezpecnost svojho software complet naruby.
Dmagician
Profil
Toto robi resize->upload

http://www.radinks.com/upload/applet.php

http://upload.thinfile.com/image/demo.php

ale je to java applet (pouziva sa to drag and drop a lite verzia na radinks ma limit 500kb subor)

takze zatial to vyzera na jedinu moznost, javu.
anode
Profil
anode: a aky bol ucel tvojho prispevku? Frflat a flejmovat? ;))
Nevím, jestli jsi četl můj příspěvek, protože účelem bylo uvést přinejmenším 3 fakta:
1) imagecreatefromjpeg bude vždy brát stejně paměti, ať je napsán sebelíp, protože má za úkol v paměti vytvořit bitmapu zadaného obrázku, která tam má zůstat i po skončení imagecreatefromjpeg(). O žádný poorman's imagecreatefromjpeg() se proto nemá smysl pokoušet.
2) že jiné řešení na serveru neexistuje. Můžeme to zachránit appletem, který polovina lidí vůbec nespustí, nebo javascriptem, který neúměrně zahltí klienta.
3) že řešení je v přechodu na jiný hosting. Co se týče (ne)možnosti takového provozování na virtual hostingu, tak jde pouze o to, kolik povolil správce paměti, a například na station.cz mají memory limit 50MB, což by snad už mohlo stačit.
Dmagician
Profil
1) ide o zmensenie obrazku ktore by fungovalo aj na nizsich memory-limitoch. O taku funkciu sa ma zmysel pokusat. Aj ked samozrjeme koncilo by to vytazovanim harddisku servera, takze nie je velmi realne ze sa take nieco objavi.

2) suhlasim applet nie je elegantne riesenie, je to onicom. Ale je jedine existujuce v pripade ze by to niekto naozaj vyzadoval (teda este okrem microsoftackeho "pluginu" ImageResizerPowertoy kde na pravy klik je zavesene kontextove menu na rychly resize obrazkov, ale tam clovek musi pracovat na suboroch na disku a na takuto ulohu potrebuje a) naistalovat tento plugin b) zaucit ho pouzivat )

3) ano urcite existuje hosting ktory ti umozni zvysit limit pamati. Ale kedze ide o funkciu ktora vyrazne vytazuje server, myslim ze je daleko realnejsie dosiahnut takyto komfort na vlastnom serveri. Zmensovanie X megapixelovych fotiek z digitalov nie je pre akokolvek vykonny pocitac ziadna sranda.
Anonymní
Profil *
Zdravim chlapi!

to anode

"Jenom pár poznámek:
1) "čekat na optimalizaci imagecreatefromjpeg()" je docela zbytečné - vždyť vytváří v paměti bitmapu ze zvoleného JPEG obrázku, méně paměti prostě z principu brát nemůže"

- jasne ze vytvari bitmapu, kdyz jpeg dekomprimuje, ale jelikoz dekodovani a nasledna dekomprimace probiha obvykle po 8x8^3 bit blocich a resampling taktez po techto blocich a jejich zpetna komprimace a zakodovani take, pak nechapu proc tvurce nenapsal rovnou imageresizejpeg(in,out) a misto toho nejprve do pameti "rozbali" jpeg na gigantickou bitmapu, pak ceka na usera nez ten zavola imagecopyresampled(), a pote logicky kazdy zavola imagejpeg()...Rozhodne nechci nikoho kritizovat, ale optimalizace by spocivala v tom spojit tyhle tri funkce dohromady do jedne a zpracovavat jpeg po 8x8^3 blocich a postupne je ukladat do jpeg souboru, pak by naklady na pamet byli hluboko pod hranici beznych hostingu i u velikych souboru, protoze by na velikosti zavisela jen delka zpracovani (CPU) a ne velikost pameti, protoze by se v jednom kroku zpracovavalo 64x64x64 bitu dat + data na promene, instrukce, callback funkci...

Zkousel sem vsechno mozne vcetne ActionScriptu (Flash) , FLEX aplikace, protoze ty maji pristup k datum klienta, ale ackoliv panove z Adobe&Macromedia se naparuji jak jsou jejich vyvojova prostredi novou generaci RIA aplikaci, jak delaji z tvorby webovych aplikaci hracku, tak nepriznaji, ze jejich mega aplikace neumi tak zakladni ukon jako je zmensit obrazek a ULOZIT HO DO SOUBORU !!! Boze !!! :-) Tenhle aplikacni soft, totiz umi jen zobrazit,zmensit nebo prehrat, ale neumi manipulovat s souborem (vyjma ciste binarnich operaci) a napr. ho ulozit!!! Coz je jedna ze zakladnich operaci, kterou umeli i ty nejprimitivnejsi programovaci jazyky :-) Kdybych vedel jak naprogramovat neco co se muze zkompilovat do php releasu, tak se do ty funkce snad fakt pustim :-)
Joker
Profil
Tenhle aplikacni soft, totiz umi jen zobrazit,zmensit nebo prehrat, ale neumi manipulovat s souborem (vyjma ciste binarnich operaci) a napr. ho ulozit!!!
Tak je to totiž napsané schválně, z důvodů bezpečnosti. Třeba JavaScript taky nemá přístup k souborům.

Nicméně mohl byste udělat třeba Flashovou aplikaci pro upload, ve které by uživatel vybral obrázek, ten by se pak zmenšil a odeslal na server?
Anonymní
Profil *
Jojo, bezpecnost predevsim. Souhlasim, ale pokud se nekdo honosi pojmem RIA - rich internet aplication, tak by mel mit moznost nastavit a odstranit docasne tato zabezpeceni. Protoze si myslim, ze manipulace se souborem je jedna ze zakladnich operaci, kterou programator provadi celkem casto, protoze logicky potrebuje manipulovat s daty uzivatele - a to v momente kdy si to uzivatel preje a vyzaduje. jina vec je to ze uz samotny koncept flash sw na klientovi neni bezpecny, ale stejne tak browser, ktery pristupuje k datum klienta by tedy podle vas nebyl bezpecny, a jak vidno mnoho z nich take trpi mnoha bezp. dirkami :-) ale co by pak podle vas bylo bezpecne ? Pak by se clovek musel vratit 10 let zpet, a odpojit pocitac od internetu zavrit ho do klece, a zahodit klic :-) Myslim ze reseni je v rozumnem kompromisu, a ten Flex/Flash proste zatim v tehle oblasti neposkytuje, a navic zneuzit se da prece vse ne ? :-)

- ohledne vasi otazky, s uploadem pres flash. To samozrejme jde, a je svele ze napr. na rozdil od php, ktere nemuze pristoupit na klienta, a narozdil od naprosto neschopnych browseru v oblati uploadu vice souboru najednou, tohle Flash od verze 8 vyresil na prani mnoha :-) Takze tohle jde pres API FileReferenceList ve Flashi. Ovsem zas neumi jine veci :-) Ale dokonale veci neexistuji!
mila
Profil
Stejný problém jsem řešil asi před dvěma dny a zůstal nevyřešen. Povzbuzen touto diskuzí jsem začal hledat, a našel jsem dvě řešení:

- exif thumbnail - jpeg obrázek má v sobě uložený náhled stejně jako třba typ fotoaparátu. Takže proč náhled vytvářet, když už je?:) Případně lza zpracovat (zmenšit - zvětšní z toho udělá hnus) ten náhled. fce exif_thumbnail

- Knihova magickwand Měla by umět zmešit obrázky i když není dost paměti. Problém je, že se musí být na serveru nainstalována + api k ní (asi tam nepůjde volat exec) Takže http://pecl.php.net/package/imagick/ či http://www.magickwand.org/download/php/

Klíčovým bodem v mém vyhledávání byl phpthumb Co jsem tak pochopil, tak by měl umět používat výše zmíněnou knihovnu (a na několika místech propaguje zmenšení obrázků i bez paměti)
A měl by také vytvářet zmenšeniny z těch thumbnailů. GPL licence
anode
Profil
Když už se zmiňuje použití ImageMagick, třída Image_Transform z PEAR to umí taky a je vydávána pod méně restriktivní PHP License. Doprogramování, aby se používal případný exif thumbnail je otázka chvíle. Problém je, že se na thumbnail nelze spolehnout.
Mimochodem, když už tu byla zmiňována náročnost celého procesu, myslím, že při správném cachování v tom není problém, holt každou fotku z galerie server jednou zmenší...
mila
Profil
řída Image_Transform z PEAR to umí taky
Moc jsem tu třídu nezkoumal, ale hlavní problém je asi přístup k ImageMagick. Volat exec na hostingu (a přistupovat tak rovnou) asi nepůjede. Tzn podstatná je přítomnost api, které jsem odkazval výše. Nechce se mi teď dívat do kódu, ale zajímalo by mě, jak to ty třídy řeší.
vydávána pod méně restriktivní PHP License
Vlastní ImageMagick je pod licencí "compatible with the GPL". Tzn. pokud ji použiji, stejně se jejích restrikcí nevyvaruji.

Problém je, že se na thumbnail nelze spolehnout
Jasně, ale myslím, že to může být často řešení, a mě prvně nenapadlo. Konkrétně dělám fotogalerii, kde se přes ftp nahrají fotky, a mají se vytvořit thumbnaily. Je to pro jeden konkrétní případ, a jestli ten jeden konkrétní fotoaparát thumbnaily ukládá, tak mám po starostech...
Toto téma je uzamčeno. Odpověď nelze zaslat.

0