/ 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
Nyt forsøg - gråtone en gif
Fra : Lars Erik Bryld


Dato : 20-03-07 14:51

Min gamle tråd gik død, men jeg håber fortsat på hjælp eller påpegning
af oplagte fejl i nedenstående forsøg på at konvertere et script fra
python (som jeg ikke kan) til PHP (som jeg kun kan lidt af):


Scriptet skal indlæse filen "ind.gif" og udspytte filen "ud.gif", som
bør ligne den oprindelige fil, blot i gråtoner. Mit nuværende forsøg
giver desværre kun en få hundrede bytes lang fil, som ikke er en valid
gif-fil.


Python-originalen:

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())


PHP-oversættelse (som ikke virker):

$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);

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



--
Med venlig hilsen
Lars Erik Bryld

 
 
Arne Feldborg (22-03-2007)
Kommentar
Fra : Arne Feldborg


Dato : 22-03-07 08:13

Lars Erik Bryld <larserik@dadlnet.invalid> skrev Tue, 20 Mar 2007
14:51:13 +0100

>Min gamle tråd gik død, men jeg håber fortsat på hjælp eller påpegning
>
Er dere nogen bestemt grund til, at du absolut vil gøre det på den
måde.?

For mig virker det som en lidt usikker metode. Og iøvrigt mener jeg kun
det er de 3 laveste bits der efter en smart formel (værdi+1)*2 angiver
antallet af farver (som så skal ganges med 3 for at få antallet af
bytes).

Og da 3 bit højst kan antage værdien 7 giver det et max antal på 16
farver. Men et gif billede kan dog mig bekendt antage 256 farver.?

Hvorfor bruger du ikke bare GdLib eller ImageMagic, som har de
nødvendige rutiner indbygget.?

--
mvh, A:\Feldborg

Slægtsforskning og lokalhistorie i midt- vestjylland
http://hammerum-herred.dk/

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


Dato : 23-03-07 19:24

Scripsit Arne Feldborg:

> Er dere nogen bestemt grund til, at du absolut vil gøre det på den
> måde.? For mig virker det som en lidt usikker metode.

Det korte svar er ja. Metoden burde ikke være usikker, hvis ellers den
gjorde som hensigten var.

> Og iøvrigt mener jeg kun det er de 3 laveste bits der efter en smart
> formel (værdi+1)*2 angiver antallet af farver (som så skal ganges
> med 3 for at få antallet af bytes). Og da 3 bit højst kan antage
> værdien 7 giver det et max antal på 16 farver. Men et gif billede
> kan dog mig bekendt antage 256 farver.?

Det er kun de 3 sidste bits i byte 10 som er interessante. Det er
derfor man laver "AND 7". Fordi 7 er lig med 111, så bør resultatet af
en AND 7 være, at kun de 3 sidste bits kan være andet end nuller.

Det er forkert, at 3 bits kun kan antage 7 værdier. Der er 000, 001,
010, 011, 100, 101, 110 og 111, dvs 8 værdier. Læg 1 til og ryk alt 2
pladser til venstre med nuller efter, så har du et tal mellem 2 og
256, som er farvepaletten.

> Hvorfor bruger du ikke bare GdLib eller ImageMagic, som har de
> nødvendige rutiner indbygget.?

Fordi det her burde kunne virke, og fordi jeg ønsker at forstå,
hvorfor det ikke gør det alligevel.

--
Med venlig hilsen
Lars Erik Bryld

Arne Feldborg (23-03-2007)
Kommentar
Fra : Arne Feldborg


Dato : 23-03-07 21:47

Lars Erik Bryld <larserik@dadlnet.invalid> skrev Fri, 23 Mar 2007
19:23:53 +0100


>> Og iøvrigt mener jeg kun det er de 3 laveste bits der efter en smart
>> formel (værdi+1)*2 angiver antallet af farver (som så skal ganges
>> med 3 for at få antallet af bytes). Og da 3 bit højst kan antage
>> værdien 7 giver det et max antal på 16 farver. Men et gif billede
>> kan dog mig bekendt antage 256 farver.?
>
>Det er kun de 3 sidste bits i byte 10 som er interessante.
>
Det var jo også lige netop det jeg skrev, men i dit eget første indlæg
skrev du selv de 4 mindste bits.

>Det er forkert, at 3 bits kun kan antage 7 værdier.
>
Det har jeg heller ikke skrevet, tværtimod skrev jeg at det max. kunne
antage værdien 7. (hvilket logisk set giver 8 muligheder - idet man
altid regner nul med)

>010, 011, 100, 101, 110 og 111, dvs 8 værdier. Læg 1 til og ryk alt 2
>pladser til venstre med nuller efter, så har du et tal mellem 2 og
>256, som er farvepaletten.
>
Den må jeg lige have een gang mere.
Hvordan får du værdien 2 ud af en byte hvor de to laveste bits begge er
nul, og hvordan får du værdien 256 ud af 5 bits.?

Du skrev også tidligere at man skulle left-shifte, det skal man så
åbenbart gøre 2 gange. Der passer bare ikke helt med den specifikation
jeg har set andre steder.

At lave selve scriptet kan jeg næppe tro der kan volde de store
problemer. Men først må vi altså lige have opgaven defineret.
Kan du henvise til et sted, hvor indholdet af byte 10 (og her især de
tre laveste bits) er klart og tydelig beskrevet.?


--
mvh, A:\Feldborg

Slægtsforskning og lokalhistorie i midt- vestjylland
http://hammerum-herred.dk/

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


Dato : 23-03-07 23:25

Scripsit Arne Feldborg:

>>> Og iøvrigt mener jeg kun det er de 3 laveste bits der efter en
>>> smart formel (værdi+1)*2 angiver antallet af farver (som så skal
>>> ganges med 3 for at få antallet af bytes). Og da 3 bit højst kan
>>> antage værdien 7 giver det et max antal på 16 farver. Men et gif
>>> billede kan dog mig bekendt antage 256 farver.?
>>
>> Det er kun de 3 sidste bits i byte 10 som er interessante.
>>
> Det var jo også lige netop det jeg skrev, men i dit eget første
> indlæg skrev du selv de 4 mindste bits.

Det var også forkert - det var kun de 3 bits.

>> Det er forkert, at 3 bits kun kan antage 7 værdier.
>>
> Det har jeg heller ikke skrevet, tværtimod skrev jeg at det max.
> kunne antage værdien 7. (hvilket logisk set giver 8 muligheder -
> idet man altid regner nul med)
>
>> 010, 011, 100, 101, 110 og 111, dvs 8 værdier. Læg 1 til og ryk alt
>> 2 pladser til venstre med nuller efter, så har du et tal mellem 2
>> og 256, som er farvepaletten.
>>
> Den må jeg lige have een gang mere. Hvordan får du værdien 2 ud af
> en byte hvor de to laveste bits begge er nul, og hvordan får du
> værdien 256 ud af 5 bits.?

Det er fordi hver gang du beder mig gentage mig selv, så introducerer
jeg en ny fejl

Der skal kun left-shiftes 1 gang, ikke 2. Det var så også, hvad jeg
første gang skrev.

Og nej, jeg kan heller ikke forklare hvorfor left-shift n skulle være
ævivalent med 2^n, men jeg må konstatere det virker nu.

Problemet var ikke den ovenstående manøvre, men det at billedindholdet
ikke kom med over i filkopien.

Der var øjensynligt et problem med linien:

$rest = fread($fi, 99999999999999999999);

Øjensynligt kunne PHP ikke forholde sig til de mange 9-taller, for
efter jeg har ændret linien til:

$rest = fread($fi, 99999999);

så virker tingene perfekt. Jeg er dog stadig utilfreds med, at jeg
overhovedet behøver at sætte en for stor værdi ind dér, fordi jeg ikke
på forhånd kender giffens størrelse.

Nogen som har en bedre løsning på dén del af det?

--
Med venlig hilsen
Lars Erik Bryld

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


Dato : 24-03-07 03:01

On Fri, 23 Mar 2007 23:25:21 +0100, Lars Erik Bryld
<larserik@dadlnet.invalid> wrote:

>Der var øjensynligt et problem med linien:
>
>$rest = fread($fi, 99999999999999999999);
>
>Øjensynligt kunne PHP ikke forholde sig til de mange 9-taller, for
>efter jeg har ændret linien til:

Tjabum, det kan være, at den overflow'er og når til et negativt
resultat, men det tyder ikke umiddelbart på det.

>$rest = fread($fi, 99999999);
>
>så virker tingene perfekt. Jeg er dog stadig utilfreds med, at jeg
>overhovedet behøver at sætte en for stor værdi ind dér, fordi jeg ikke
>på forhånd kender giffens størrelse.
>
>Nogen som har en bedre løsning på dén del af det?

feof() kan fortælle dig, om du er nået til vejs ende for den aktuelle
fil-pointer.

Hvis du vil spare hukommelse, kan du indlæse få dele ad gangen, fx
8KB:

while (!feof($fi)) {
   $rest = fread($fi,8192);
   fwrite($fo,$rest);
}

Alternativt kan du bruge filesize() til at finde ud af, hvor stor, den
første fil er, og ftell() til at finde ud af, hvor meget, du har læst
indtil videre, og på den måde læse den resterende del - hvis du altså
vil læse resten i én bid.

--
- Peter Brodersen
Kendt fra Internet

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


Dato : 24-03-07 10:07

Scripsit Peter Brodersen:

> while (!feof($fi)) {
>    $rest = fread($fi,8192);
>    fwrite($fo,$rest);

Tak for tippet. Nu er der forhåbentlig ikke noget med, at den sidste
4-6 Kb stump ikke lige kommer med på den måde, vel?

--
Med venlig hilsen
Lars Erik Bryld

Arne Feldborg (24-03-2007)
Kommentar
Fra : Arne Feldborg


Dato : 24-03-07 08:11

Lars Erik Bryld <larserik@dadlnet.invalid> skrev Fri, 23 Mar 2007
23:25:21 +0100

>Der skal kun left-shiftes 1 gang, ikke 2. Det var så også, hvad jeg
>første gang skrev.
>
Jammen det er jo fordi du slet ikke gør det du selv foreslår..Og du
skrev jo dog netop, at du ville forstå hvorfor det ikke virkede i første
omgang.

Hvis vi kigger på Phyton eksemplet du kom med, så er det *ikke* tallet
fra bit 0 -2 i byte 10 der bliver leftshiftet.! Og det er grunden til
at jeg ikke i første omgang kunne se hvor det var du ville hen.

>Og nej, jeg kan heller ikke forklare hvorfor left-shift n skulle være
>ævivalent med 2^n,
>
Det er det heller ikke - det er det samme som at gange med 2.

Det der bliver leftshiftet er nemlig tallet "1" yderst til venstre, og
det bliver leftshiftet fra 1 til 8 gange.!

Det der sker er, at man lader indholdet af de tre bits bestemme hvor
mange gange tallet "1" skal ganges med 2 (=leftshiftes).

Det giver værdierne så fra 1 til 128, men da et billede jo ikke kan have
kun een farve, så har man vedtaget altid at leftshifte en gang ekstra (1
tallet længst til højre).

Det giver værdierne 2, 4, 8, 16, 32, 64, 128, og 256, men derimod ikke
de mellemligende værdier (og dem er der jo heller ikke brug for).

Da een gang leftshift er det samme som at gange med 2, og da (1+1)
tilfældigvis er det samme som (1*2) kan det opstilles på flere måder.
Disse fire vil feks alle give resultatet 256.

echo 1 << (7+1);
echo (1+1) << 7;
echo pow(2,(7+1));
echo (1+1) * pow(2,7);


Overført til dit gif-billede kan det du så bruge een af dise fire:

$l = 2 * pow(2, (ord($header[10]) & 7));

$l = pow(2, (ord($header[10]) & 7)+1);

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

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

Hvor det sidste nok er det der ligner Phyton eksemplet mest. Og altså
bliver det færdige script ca. sådanne:


<?php
$fi = fopen("in.gif", 'rb');
$fo = fopen("out.gif", 'wb');

$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, chr($gray).chr($gray).chr($gray));
}

while (!feof($fi)) {
   $contents = fread($fi,1);
   fwrite($fo, $contents);
}

fclose($fi);
fclose($fo);
exit;
?>

Det kan godt trækkes mere sammen (a'la Phyton eksemplet), men så bliver
det til gengæld også mere uoverskueligt.



--
mvh, A:\Feldborg

Slægtsforskning og lokalhistorie i midt- vestjylland
http://hammerum-herred.dk/

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


Dato : 24-03-07 10:18

Scripsit Arne Feldborg:

> Det der sker er, at man lader indholdet af de tre bits bestemme hvor
> mange gange tallet "1" skal ganges med 2 (=leftshiftes).

Mange tak for præcisionen af det! Det med faktorernes orden havde jeg
totalt misforstået, men til undskyldning synes jeg heller ikke, det er
let at finde dokumentation på bit-algebra (eller hvad det nu hedder).

Og hvis nogen skulle undre sig over formålet med at ville gråtone
billeder på den måde: Det er heller ikke det jeg vil, men jeg vil
prøve at lave et script, som kan farvekode et landkort ud fra data
trukket ud fra en database. Hvis hvert landområde får en unik farve,
så skulle man kunne omfarve landområdet ved dynamisk at ændre
farvepaletten, sådan som man jo gør i gråtonescriptet. Tanken udsprang
af en diskussion om manglende opdateringer af KIP-kortene ovre i
DIS-Danmark.

Også tak for det mere elegante forslag til at få kopieret resten af
data over.

--
Med venlig hilsen
Lars Erik Bryld

Arne Feldborg (24-03-2007)
Kommentar
Fra : Arne Feldborg


Dato : 24-03-07 15:08

Lars Erik Bryld <larserik@dadlnet.invalid> skrev Sat, 24 Mar 2007
10:18:10 +0100


>trukket ud fra en database. Hvis hvert landområde får en unik farve,
>så skulle man kunne omfarve landområdet ved dynamisk at ændre
>farvepaletten, sådan som man jo gør i gråtonescriptet. Tanken udsprang
>af en diskussion om manglende opdateringer af KIP-kortene ovre i
>DIS-Danmark.
>
Ok. Smart nok.

Det ville nok faktisk blive ret nemt at gøre.

Men det kunne du jo bare have sagt med det samme, det kunne jo gøres
både med GdLib og Image Magic uden du behøvede at kende de tekniske
detaljer bag palettens opbygning.

--
mvh, A:\Feldborg

Slægtsforskning og lokalhistorie i midt- vestjylland
http://hammerum-herred.dk/

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


Dato : 24-03-07 16:01

Scripsit Arne Feldborg:

> Det kunne jo gøres både med GdLib og Image Magic uden du behøvede at
> kende de tekniske detaljer bag palettens opbygning.

Jeg har forhåbentlig aldrig givet indtryk af at være aktivt imod at
blive klogere. Jeg ville gerne lære noget om palettens opbygning og
jeg ville om muligt også gerne skrive et script, hvor jeg slet ikke
behøvede at tænke på, om der var grafiske ekstramoduler installeret.

--
Med venlig hilsen
Lars Erik Bryld

Arne Feldborg (24-03-2007)
Kommentar
Fra : Arne Feldborg


Dato : 24-03-07 08:14

Lars Erik Bryld <larserik@dadlnet.invalid> skrev Fri, 23 Mar 2007
23:25:21 +0100


>så virker tingene perfekt. Jeg er dog stadig utilfreds med, at jeg
>overhovedet behøver at sætte en for stor værdi ind dér, fordi jeg ikke
>på forhånd kender giffens størrelse.
>
Aldrig hørt om EOF.?

>Nogen som har en bedre løsning på dén del af det?
>
while (!feof($fi)) {
   $contents = fread($fi,1);
   fwrite($fo, $contents);
}

--
mvh, A:\Feldborg

Slægtsforskning og lokalhistorie i midt- vestjylland
http://hammerum-herred.dk/

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