[php] kwaliteit jpg verlagen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ik heb een script waarmee mensen een jpg kunnen uploaden het script verkleind de jpg al tot een bepaalde grootte, alleen daarna zou hij ook nog de kwaliteit net zo lang omlaag moeten gooien tot hij onder een bepaald aantal kb zit nou kan je het doen met een tijdelijk bestand te maken en met imagejpg() in een loop de kwaliteit steeds om laag te knallen tot hij laag genoeg is en dan uiteindelijk dat tijdelijke bestand weer weg gooien maar bestaat er geen functie voor? ben al tijdje aan het zoeken maar niks gevonden tot nu toe!

voor de geinteresseerden, dit is de code tot nu toe, er zit nog geen controle op of het wel een jpg is enzo dat moet nog..
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php

$upload="../test/upload"; // map waar plaatjes heen gaan
$naam=time().".jpg"; // nieuwe naam van het plaatje
$max_width = 100; // max breedte nieuwe plaatje
$max_height = 100; // max hoogte nieuwe plaatje

$img = null;
$img = @imagecreatefromjpeg($_FILES['userfile']['tmp_name']);

if ($img) {
    $width = imagesx($img);
    $height = imagesy($img);
    $scale = min($max_width/$width, $max_height/$height);

    if ($scale < 1) {
        $new_width = floor($scale*$width);
        $new_height = floor($scale*$height);

        $tmp_img = imagecreatetruecolor($new_width, $new_height);

        imagecopyresized($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
        imagedestroy($img);
        }    
}
imagejpeg($tmp_img,$upload.'/'.$naam,100);
imagedestroy($tmp_img); 
?>


en voor het complete :) :
code:
1
2
3
4
<form enctype="multipart/form-data" action="blaat.php" method="post">
 Upload dit bestand: <input name="userfile" type="file">
 <input type="submit" value="Upload!">
</form>

[ Voor 70% gewijzigd door Verwijderd op 21-01-2005 16:29 ]


Acties:
  • 0 Henk 'm!

  • RM-rf
  • Registratie: September 2000
  • Laatst online: 20:45

RM-rf

1 2 3 4 5 7 6 8 9

http://de3.php.net/manual/en/function.imagejpeg.php
bool imagejpeg ( resource image [, string filename [, int quality]] )
Wat je wilt zekerstellen is echter dat je deze functie altijd op het bronbestand blijft uitvoeren, en niet telkens verder op basis van het al eerder verwerkte bestand, aangezien jpeg lossy is, zou je anders zowel artifacten over de werkelijke image krijgen, maar ook deze artifacten zelf extra gaan comprimeren, dat leidt tot erg lelijke afbeeldingen met overduidelijke artifacten (sowieso vind ik afdingen op kwaliteit om bestandsgrootte te bespraen via een automatisch proces twijfelachtig, volgens mij is de output erg, erg lelijk)

Intelligente mensen zoeken in tijden van crisis naar oplossingen, Idioten zoeken dan schuldigen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ja dat kan zijn maar goed,
er is dus geen functie waarmee je de kwaliteit kan testen, de enige oplossing is het bestand aanmaken met imagejpeg en dan steeds weer opnieuw met het bronbestand dus en de kwaliteit steeds wat minder,
ok ga ik daar even mee testen

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

Enige mogelijkheid is het opslaan naar een tijdelijk bestand, wat een nogal heftige bezigheid kan worden denk ik voor de server :)

Blijkbaar ben je thumbnails aan het opslaan van max 100x100 pixels. Zelf doe ik dit ook regelmatig maar zelfs met 80% JPG ziet het er prima uit en worden de bestanden niet groter dan 2-3K.. Beetje zonde om dan zo ingewikkeld en serverintensief iets te gaan doen voor een paar bytes minder.

[ Voor 54% gewijzigd door Bosmonster op 21-01-2005 17:30 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
het formaat is nu idd thumbnail,
de bedoeling is dat mensen gewoon foto's kunnen uploaden
binnen een bepaald formaat, zeg 300 bij 300 ofzo
en niet groter dan bijvoorbeeld 50kb
nu zou je simpelweg kunnen zeggen verklein zelf maar,
maar ik dacht laat ik iets proberen om hem zelf kleiner te maken
de kwaliteit omlaag dus,

ik heb nu dit gedaan:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$img = @imagecreatefromjpeg($upload.'/'.$naam);

$quality=80;

while (filesize($upload.'/'.$naam)>$max_kb){
    
    $size=filesize($upload.'/'.$naam);
    print "<br>kwaliteit: $quality - grootte: $size";
    
    
    unlink($upload.'/'.$naam);
    $tmp_img = imagecreatetruecolor($new_width, $new_height);
    $tmp_img = $img;
    imagejpeg($tmp_img,$upload.'/'.$naam,$quality);
    imagedestroy($tmp_img);
    $quality=$quality-5; 
}
//imagedestroy($img);

$size=filesize($upload.'/'.$naam);

print " 
 <br>naam: $naam
 <br>originele grootte: $originele_grootte
 <br>nieuwe grootte: $size
 <br>max grootte: $max_kb
 <br>width: $width
 <br>height: $height
 <br>scale: $scale
 <br>new width: $new_width
 <br>new height: $new_height
 <br>[img]\"$upload/$naam\"[/img]";


de onderkant is slechts ter controle,
alleen om de 1 of andere reden loopt deze lus steeds na 2 stappen vast en dan krijg je de volgende melding in beeld:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
kwaliteit: 80 - grootte: 34979
kwaliteit: 75 - grootte: 8970
Warning: imagejpeg(): 6 is not a valid Image resource in /home/virtual/site116/fst/var/www/html/test/blaat.php on line 46

Warning: imagedestroy(): 6 is not a valid Image resource in /home/virtual/site116/fst/var/www/html/test/blaat.php on line 47

Warning: filesize(): Stat failed for ../test/upload/1106325148.jpg (errno=2 - No such file or directory) in /home/virtual/site116/fst/var/www/html/test/blaat.php on line 37

Warning: filesize(): Stat failed for ../test/upload/1106325148.jpg (errno=2 - No such file or directory) in /home/virtual/site116/fst/var/www/html/test/blaat.php on line 52

naam: 1106325148.jpg 
originele grootte: 21504 
nieuwe grootte: 
max grootte: 5000 
width: 288 
height: 352 
scale: 0.56818181818182 
new width: 163 
new height: 200


ik heb geen flauw idee hoe dat kan eigenlijk :+
los van de error is het verschil in grootte ook NOGAL heftig,
en hij begint met een grootte die groter is dan de orignele grootte :?

[ Voor 9% gewijzigd door Verwijderd op 21-01-2005 17:40 ]


Acties:
  • 0 Henk 'm!

Verwijderd

PHP:
1
    $tmp_img = imagecreatetruecolor($new_width, $new_height);

die hoeft al niet meer omdat imagecreatefromjpeg() al een nieuw plaatje maakt.. haal vervolgens eens die @ weg zodat je de error ziet :P

zou je btw niet met een tijdelijk bestand werken ipv meteen het origineel te overschrijven? bij succes kun je nog altijd het origineel wegflikkeren

[ Voor 26% gewijzigd door Verwijderd op 22-01-2005 02:23 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Dat je vage errors krijgt komt waarschijnlijk omdat filesize() op een rare manier gecached wordt en niet weet dat je bestand steeds van grootte verandert.

Het is een smerige hack, maar je kan je filename ook weglaten. Dan schrijft imagejpeg naar de output stream, en als je daar een output buffer omheen gooit kun je de (grootte van de) jpeg data opvangen zonder file I/O.

Ook kun je die quality waarde inklemmen tussen een min- en max-waarde, zo heb je in veel gevallen minder vergelijkingen nodig dan met "$quality = $quality - 5".

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    $img = imagecreatefromjpeg('testplaatje.jpg');

    $minQ=0; $maxQ=100;
    $max_bytes=50000;

    ob_start();
    do {
        ob_clean();
        $quality = ($minQ + $maxQ) / 2;
        imagejpeg($img, '', $quality);

        if (ob_get_length() > $max_bytes) {
            $maxQ = $quality;
        } else {
            $minQ = $quality;
        }
    } while ($maxQ-$minQ > 3);
    ob_end_clean();

    $quality = $minQ;

[ Voor 4% gewijzigd door Verwijderd op 22-01-2005 04:36 . Reden: 't is laat ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op zaterdag 22 januari 2005 @ 02:21:
PHP:
1
    $tmp_img = imagecreatetruecolor($new_width, $new_height);

die hoeft al niet meer omdat imagecreatefromjpeg() al een nieuw plaatje maakt.. haal vervolgens eens die @ weg zodat je de error ziet :P

zou je btw niet met een tijdelijk bestand werken ipv meteen het origineel te overschrijven? bij succes kun je nog altijd het origineel wegflikkeren
ik overschrijf het orignineel toch ook pas als de grootte goed is?
het origineel is $img, die pakt hij steeds weer in $tmp_img, totdat het goed is
Pagina: 1