[PHP]binair file manipulatie: online gif headers veranderen?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • henkleerssen
  • Registratie: December 2000
  • Niet online

henkleerssen

Your life is as you narrate it

Topicstarter
Elk gifje heeft (als het goed is) een kleur code tabel: een tabel waar alle RGB kleuren hexadecimaal in de header zijn opgeslagen.
Op basis van een php script zou ik graag een van deze kleuren veranderen, door direct in deze code tabel te schrijven van een gif (op een bepaalde index positie).
Nee, ik wil niet de GD lib gebruiken (ondersteund webhoster niet.. en is onnodige belasting van de server lijkt me). Ik google me weer rot.. maar vind weer niks.
(Wat ik wel gevonden heb is dechex om eventueel wat berekeningen te doen in decimalen voor kleur aanpassing zie ook http://www.tonymarston.net/php-mysql/converter.html voor verdere calculatie).
Fopen open je wel een stream mee.. maar hoe kan ik deze bit voor bit/hexadecimaal voor hexadecimaal uitlezen (standaard w+ parameter lijkt me niet de oplossing)?

Wie oh wie heeft een verlossend antwoord?

[ Voor 3% gewijzigd door henkleerssen op 27-11-2005 17:17 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Kan je niet gewoon heel de file inlezen en dan de file alks array behandelen: array van chars. Vervolgens de benodigde offsets weizigen en dan hele array van chars wegschrijven?

volgens mij kan je namelijk niet zeg maar zeggen
; wijzig die bit van die byte op positie x in file y in PHP. En kan dat ook niet zo 1...2...3 vinden. Weet wel, bij grote files is mijn methode ook wel traagjes, maar zou geen obstakel moeten zijn bij standaard gifjes.

[ Voor 44% gewijzigd door Verwijderd op 27-11-2005 17:28 ]


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:14
Hier staat een specificatie van het bestandsformaat:
http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt
Lees die eerst maar eens (selectief) door, dan weet je hoe je het palet kunt vinden in het bestand. Verder is het nuttig om een hex editor te gebruiken om te bekijken hoe zo'n bestand er nu uit ziet.

In principe zou je met fseek fread toe moet kunnen om de zinnige delen van het bestand uit te lezen en met fwrite kun je je wijzigingen weer schrijven.

Alternatief kun je het hele bestand inlezen, in het geheugen wijzigen en weer wegschrijven, zoals Hel Gast voorsteld. GIF bestanden zijn meestal niet zo groot, dus dat moet niet echt een probleem zijn, maar nodig is het absoluut niet.

Acties:
  • 0 Henk 'm!

  • henkleerssen
  • Registratie: December 2000
  • Niet online

henkleerssen

Your life is as you narrate it

Topicstarter
mm ik wist niet van het bestaan van fseek.. had wat beter moeten zoeken blijkbaar.. Daar kan ik wel wat mee. thnx!
Die specs van gif89a had ik al .. (of was het nou van 87?) .. vandaar dat ik er ook achter kwam om deze te manipuleren.
Om nou het hele bestand te gaan inlezen (het is op zich niet zo groot.. maar ik wil de server weer niet te veel belasten he.. ), vind ik wat overdreven. En daarbij moet ik nog die chars naar hex waarde converteren... hoe? charhex?

Acties:
  • 0 Henk 'm!

Verwijderd

ord(char) geeft integerwaarde van char
Dan kan je gaan hexxen met dechex, als het nodig is

(en serverbelasting: als je bestandsysteem een beetje niet-gefragmenteerd is, bufferd je hardisk in een klap heel zon gifje, als ze echt klein zijn. Maar om te kijken wat sneller is, zal je toch wel effe een benchmarkje moeten draaien (beide methodes over 10.000 gifjes halen ofzo) en dan kijken wat het snelste is.)

[ Voor 64% gewijzigd door Verwijderd op 27-11-2005 19:02 ]


Acties:
  • 0 Henk 'm!

  • henkleerssen
  • Registratie: December 2000
  • Niet online

henkleerssen

Your life is as you narrate it

Topicstarter
Verwijderd schreef op zondag 27 november 2005 @ 19:00:
ord(char) geeft integerwaarde van char
Dan kan je gaan hexxen met dechex, als het nodig is

(en serverbelasting: als je bestandsysteem een beetje niet-gefragmenteerd is, bufferd je hardisk in een klap heel zon gifje, als ze echt klein zijn. Maar om te kijken wat sneller is, zal je toch wel effe een benchmarkje moeten draaien (beide methodes over 10.000 gifjes halen ofzo) en dan kijken wat het snelste is.)
ga er mee aan de slag.. thnx

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
henkleerssen schreef op zondag 27 november 2005 @ 18:55:
En daarbij moet ik nog die chars naar hex waarde converteren... hoe? charhex?
Het slaat natuurlijk nergens op om die waarden letterlijk in z'n hexadecimaale representatie op te slaan, je schrijft gewoon bytes (0...255) waarbij het wel vaak handig is om die notatie te gebruiken ("\xFF" etc) zodat 't duidelijk is wat je doet. Niets weerhoud je er echter van om die tekens in ASCII notatie op te slaan, ("a"). Dezelfde byte word namelijk weggeschreven.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Wellicht kan je nog wat nuttige dingen halen uit mijn javascript GIF implementatie

Sec gezien* hebben de meeste gifjes een global colortable die begint op positie 14 en 3 x 2 ^ kleurdiepte groot is. Elke kleur wordt in 3 bytes opgeslagen als RGB waarde.
De colortable is dus niet voor elk gifje even groot, en is meestal ook niet gesorteerd. Eveneens heeft de backgroundcolor niet een vaste index, net als de kleur die voor eventuele transparantie wordt gebruikt.

* Een gif hoeft geen colortable te hebben, en daarbij kan een plaatje in een gif (een gif kan meerdere plaatjes bevatten) ook een local colortable hebben.

[ Voor 40% gewijzigd door crisp op 27-11-2005 21:56 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • henkleerssen
  • Registratie: December 2000
  • Niet online

henkleerssen

Your life is as you narrate it

Topicstarter
crisp schreef op zondag 27 november 2005 @ 21:51:
Wellicht kan je nog wat nuttige dingen halen uit mijn javascript GIF implementatie

Sec gezien* hebben de meeste gifjes een global colortable die begint op positie 14 en 3 x 2 ^ kleurdiepte groot is. Elke kleur wordt in 3 bytes opgeslagen als RGB waarde.
De colortable is dus niet voor elk gifje even groot, en is meestal ook niet gesorteerd. Eveneens heeft de backgroundcolor niet een vaste index, net als de kleur die voor eventuele transparantie wordt gebruikt.

* Een gif hoeft geen colortable te hebben, en daarbij kan een plaatje in een gif (een gif kan meerdere plaatjes bevatten) ook een local colortable hebben.
ziet er interessant uit dat voorbeeldje! geïnspireerd door het werk van Walter Zorn of zo? En/of zelf gebakken javascript?
die local color table wist ik idd..en dat het een en ander niet geïndexeerd is (das geen punt meer met fseek).. Maar ik beheer zelf de kleuren van het gifje . dus ik weet wat er in staat.
Maar het enige waar ik ff niet uitkom hoe je nou weet welke kleur nu transparant is (zonder naar de gif zelf te kijken en aleen naar de headers he).

offtopic:
pssst...dat voorbeeldje werkt niet helemaal lekker crisp.. Opera zie je heel traag de menu items voorbij komen en in IE zie je wel menu items maar doen deze weer niks? Kan ook aan mijn trage office bak van 800 mhz komen waar ik nu achter zit misschien.. ik zou nog moeten kijken op mijn andere meer up to date pc'tje.. Neemt allemaal niet weg dat ik er eens wat aan zou kunnen hebben.

[ Voor 16% gewijzigd door henkleerssen op 27-11-2005 23:21 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Zelf gebakken :)

Transparancy zit in een zogenaamd Graphic Control Extension block. Na de global colortable volgen de extensions die te herkennen zijn aan de extension introducer byte (33) gevolgd door een label (voor de graphic control extension is dat 249).
Vervolgens moet je kijken in dat block of de tranparency bit in de descriptor geset is, zo ja dan staat de index in de laatste byte (zie http://www.danbbs.dk/~dino/whirlgif/gif89.html#sec23)

Je kan hier dus niet puur met fseek gaan werken; je moet echt de blocks af en niet-interessante blocks skippen (zoals bijvoorbeeld eventuele comment-blocks enzo); in feite doe ik dat met dit stukje code:

JavaScript:
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
    //-- skip extensions, except Graphic Control Extension
    var numblocks;
    var TransparentColorIndex = -1;
    while (data.charCodeAt(i) == 33)
    {
        if (data.charCodeAt(++i) == 249)
        {
            // Graphic Control Extension gives us transparency
            i += 2;
            descriptor = data.charCodeAt(i);
            if (descriptor & 1)
            {
                i += 3;
                TransparentColorIndex = data.charCodeAt(i);
                i += 2;
            }
            else
            {
                i += 5;
            }
        }
        else
        {
            // we don't care what extension it is, just read how many bytes to skip
            i += 1;
            while ((numblocks = data.charCodeAt(i++)) != 0)
            {
                i += numblocks;
            }
        }
    }


offtopic:
Dit is work in progress en ik werk voornamelijk in Firefox. Achter het menu zitten idd nog geen acties.

Intentionally left blank

Pagina: 1