/ Forside / Teknologi / Udvikling / PHP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
PHP
#NavnPoint
rfh 3959
natmaden 3372
poul_from 3310
funbreak 2700
stone47 2230
Jin2k 1960
Angband 1743
Bjerner 1249
refi 1185
10  Interkril.. 1146
Manipulere GIF-farvepalet uden GD-lib etc
Fra : Lars Erik Bryld


Dato : 16-03-07 15:53

Hej gruppe


Jeg prøver uden større held at oversætte et lille python-script til
PHP.

Scriptet skal indlæse en GIF-fil og ændre dennes farvepalet samt
spytte resultatet ud i en ny GIF-fil. Som en indledende øvelse blot
ændre alle farver til gråtoner. I python gøres dette angiveligt
således:

header = f.read(13)
o.write(header)
for i in range (1 << (( ord(header)[10]) & 7) + 1)):
gray = (ord(f.read(1) + ord(f.read(1) + ord(f.read(1)))/3
o.write(3*chr(gray))
o.write(f.read())


Tricket er, at en GIF-fil består af en 13 byte lang header, så en
farvepalet, hvis længde kan bestemmes ved at left-shifte de nederste 4
bits i headerens byte 10, og endelig selve billedets data. Paletten
består af 3-byte grupper for henholdsvis R, G og B, og scriptet laver
gråtonen som et simpelt gennemsnit af værdien for henholdsvis R, G og
B. Scriptet kopierer først headeren, ændrer så paletten og kopierer
til sidst billeddata uændret.

Mit første og ikke-virkende forsøg på at oversætte scriptet lød sådan:

$fi = fopen("in.gif", r);
$fo = fopen("out.gif", w);

$header = fread($f1, 13);
$fo = fwrite($header);

for i = 1 to (1 << ($header[10] & 7) + 1) {
$gray = (fread($fi, 1) + fread($fi, 1) + fread($fi, 1))/3;
$fo = fwrite(3*($gray));
}

$fo = fwrite( fread($fi) );

$ssb = fclose($fi);
$ssf = fclose($fo);


Den går galt, når der skal til at bit-manipuleres, og jeg indrømmer
blankt, at jeg ikke har brugt nogle gode PHP-ækvivalenter til
python-funktionerne ord() og chr(), som vel nærmest konverterer mellem
binært talsystem og decimaltalsystem.

Men dertil kommer, at jeg ikke er sikker på, at jeg har forstået,
hvordan man åbner og byte-manipulerer binære filer, så jeg ville være
taknemmelig for at få at vide, hvordan scriptet burde se ud for at
virke.


--
Med venlig hilsen
Lars Erik Bryld

 
 
Peter Brodersen (16-03-2007)
Kommentar
Fra : Peter Brodersen


Dato : 16-03-07 16:24

On Fri, 16 Mar 2007 15:52:45 +0100, Lars Erik Bryld
<larserik@dadlnet.invalid> wrote:

>$fi = fopen("in.gif", r);
>$fo = fopen("out.gif", w);

Både r og w er strenge, så de skal fx angives som 'r' og 'w'

For en god ordens skyld kan du angive, at du arbejder med binære
filer, fx 'rb' og 'wb' som nævnt under fopen():
http://php.net/fopen

>Den går galt, når der skal til at bit-manipuleres, og jeg indrømmer
>blankt, at jeg ikke har brugt nogle gode PHP-ækvivalenter til
>python-funktionerne ord() og chr(), som vel nærmest konverterer mellem
>binært talsystem og decimaltalsystem.

Hvad med PHP-funktionerne ord() og chr() ?
http://php.net/ord
http://php.net/chr

--
- Peter Brodersen
Kendt fra Internet

Lars Erik Bryld (16-03-2007)
Kommentar
Fra : Lars Erik Bryld


Dato : 16-03-07 20:32

Scripsit Peter Brodersen:

>> blankt, at jeg ikke har brugt nogle gode PHP-ækvivalenter til
>> python-funktionerne ord() og chr(), som vel nærmest konverterer
>> mellem binært talsystem og decimaltalsystem.
>
> Hvad med PHP-funktionerne ord() og chr() ?
> http://php.net/ord
> http://php.net/chr

Avs....

Nå, nu har jeg lavet noget, som ikke uspyr tonsvis af fejlmeddelelser,
men hvor outputfilen kun er mellem 14 og 300 bytes lang, selv om
udgangsfilen er en 47 kB GIF. Det ser ud til, at kun header og palet
slipper over i den ny fil. Er der en oplagt grund til det?

$fi = fopen("in.gif", 'r');
$fo = fopen("out.gif", 'w');

$header = fread($fi, 13);
fwrite($fo, $header);

$l = (1 << (ord($header[10]) & 7) + 1);

for ($i = 0; $i <= $l; $i++) {
$gray = (ord(fread($fi, 1)) + ord(fread($fi, 1)) + ord(fread($fi,
1)))/3;
fwrite($fo, 3*chr($gray));
}

$rest = fread($fi, 99999999999999999999);

fwrite($fo, $rest);


fpassthru($fo);

fclose($fi);
fclose($fo);




--
Med venlig hilsen
Lars Erik Bryld

Søg
Reklame
Statistik
Spørgsmål : 177500
Tips : 31968
Nyheder : 719565
Indlæg : 6408514
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste