Ankündigung

Einklappen
Keine Ankündigung bisher.

GIF87a aus PHP binär erzeugen mit LZW Compression

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • GIF87a aus PHP binär erzeugen mit LZW Compression

    Hallo,
    ich habe versucht ein Palettenbild mit PHP Boardmitteln zu generieren. Die Daten stammen aus einer Quelle mit Index-Farbtabelle, einzig ist es kein für den PC anzeigbares Format. Nun möchte ich das mit PHP coden. Grundsätzlich ist das Format recht einfach, jedoch sind die Pixeldaten beim GIF immer mit LZW komprimiert. Ich habe hier http://www.matthewflickinger.com/lab...image_data.asp eine Art Anleitung dazu gefunden, aber irgendwie kommt bei mir immer nur Müll raus, sprich ein Bildbetrachter zeigt das generierte Bild nicht an.
    Fertige LZW-Libs für PHP scheinen alle(naja, hab schon einige probiert) nicht zu funktionieren, vermutlich weil die LZW-Kompression beim GIF noch irgendwie besonders ist.
    Falls jemand sich da schonmal durchgequält hat wäre ich dankbar für eine paar Tipps wie man das am besten angeht.


  • #2
    Ohne Code ist die Frage eigentlich sinnlos. Das sollte jedem logisch denkenden Menschen einleuchten, der Programmierer werden will.
    Fehler-Beschreibungen sollten den Fehler beschreiben, nicht Deine persönlich emotionale Einschätzung. Äußere auch nie Mutmaßungen sondern stelle Vergleiche gegenüber, warum Deiner Meinung nach was nicht funktionieren sollte und was Du erwartest, aber was stattdessen rausgekommen ist. Das alles anhand von handfesten Daten und Beispielen inkl. Deinem Code.

    bitcoin.de <- Meine Freelancerwährung

    Kommentar


    • #3
      ich habe versucht ein Palettenbild mit PHP Boardmitteln zu generieren
      Dann zeig mal.

      Kommentar


      • #4
        Also, hier die Funktionsbeschreibung aus obigem Link:

        LZW compression is used in GIF files to reduce file size. (Actually it is a slight variation from the standard LZW for use in GIF images.) This method requires building a code table. This code table will allow us to use special codes to indicate a sequence of colors rather than just one at a time. The first thing we do is to initialize the code table. We start by adding a code for each of the colors in the color table. This would be a local color table if one was provided, or the global color table. (I will be starting all codes with "#" to distinguish them from color indexes.)
        #0 0
        #1 1
        #2 2
        #3 3
        #4 Clear Code
        #5 End Of Information Code
        I added a code for each of the colors in the global color table of our sample image. I also snuck in two special control codes. (These special codes are only used in the GIF version of LZW, not in standard LZW compression.) Our code table is now considered initialized.

        Let me now explain what those special codes are for. The first new code is the clear code (CC). Whenever you come across the clear code in the image data, it's your cue to reinitialize the code table. (I'll explain why you might need to do this in a bit.) The second new code is the end of information code (EOI). When you come across this code, this means you've reached the end of the image. Here I've placed the special codes right after the color codes, but actually the value of the special codes depends on the value of the LZW minimum code size from the image data block. If the LZW minimum code size is the same as the color table size, then special codes immediately follow the colors; however it is possible to specify a larger LWZ minimum code size which may leave a gap in the codes where no colors are assigned. This can be summarized in the following table.
        2 #0-#3 #4 #5
        3 #0-#7 #8 #9
        4 #0-#15 #16 #17
        5 #0-#31 #32 #33
        6 #0-#63 #64 #65
        7 #0-#127 #128 #129
        8 #0-#255 #256 #257
        Before we proceed, let me define two more terms. First the index stream will be the list of indexes of the color for each of the pixels. This is the input we will be compressing. The code stream will be the list of codes we generate as output. The index buffer will be the list of color indexes we care "currently looking at." The index buffer will contain a list of one or more color indexes. Now we can step though the LZW compression algorithm. First, I'll just list the steps. After that I'll walk through the steps with our specific example.
        • Initialize code table
        • Always start by sending a clear code to the code stream.
        • Read first index from index stream. This value is now the value for the index buffer
        • <LOOP POINT>
        • Get the next index from the index stream to the index buffer. We will call this index, K
        • Is index buffer + K in our code table?
        • Yes:
          • add K to the end of the index buffer
          • if there are more indexes, return to LOOP POINT
        • No:
          • Add a row for index buffer + K into our code table with the next smallest code
          • Output the code for just the index buffer to our code steam
          • Index buffer is set to K
          • K is set to nothing
          • if there are more indexes, return to LOOP POINT
        • Output code for contents of index buffer
        • Output end-of-information code

        und hier mein bisheriger Code dazu (klappt nicht, klar, weil ichs nicht ganz kapier):

        PHP-Code:
        function gif_lzw_data($index_stream)
        {
            
        $code_stream ''# compressed output
            
        $index_buffer '';

            
        $lzw_min_code_size 8;
            
        $color_codes pow(2$lzw_min_code_size);
            
        $clear_code pack("C"$color_codes 1);
            
        $eoi_code pack("C"$color_codes 2);

            
        // initialize code table
            
        $code_table '';
            for (
        $i 0$i <= $color_codes$i++)
            {
                
        $code_table .= pack("C"$i);
            }
            
        $code_table .= $clear_code;
            
        $code_table .= $eoi_code;

            
        $code_stream .= $clear_code;
            
        $index_buffer substr($index_stream01);
            for (
        $i 1$i strlen($index_stream); $i++)
            {
                
        $K substr($index_stream$i1);
                
        $index_buffer .= $K;
                if (
        mb_strpos($code_table$index_buffer $K0"8BIT"))
                {
                    
        $index_buffer .= $K;
                    
        $K '';
                }
                else {
                    
        $code_table .= $index_buffer $K;
                    
        $code_stream .= $index_buffer;
                    
        $index_buffer $K;
                    
        $K '';
                }
            }
            
        $code_stream .= $index_buffer# ??? Output code for contents of index buffer
            
        $code_stream .= $eoi_code;

            return 
        $code_stream;

        Kommentar


        • #5
          Zitat von phreund Beitrag anzeigen
          ich habe versucht ein Palettenbild mit PHP Boardmitteln zu generieren.
          Du hast hier vor einigen Tagen schon zu "Bild in PHP mit Farbpalette (256 indexed colors) erzeugen" ein Thema aufgemacht. Ein Feedback zu den Vorschlägen dort vermisse ich.
          Dort war von PNG die Rede, hier von Gif. PHP kann genau so auch Gif87a erzeugen.

          Zitat von phreund Beitrag anzeigen
          Die Daten stammen aus einer Quelle mit Index-Farbtabelle, einzig ist es kein für den PC anzeigbares Format.
          Wenn hier dein Problem liegt, dann zeige uns an einem Beispiel wie diese Daten vorliegen.
          PHP-Klassen auf github

          Kommentar


          • #6
            was spricht gegen:
            http://php.net/manual/de/function.imagegif.php

            oder siehst Du das eher sportlich?

            sorry jspit habe Deinen Beitrag (noch) nicht gesehen...

            Kommentar


            • #7
              Die Probleme hängen zusammen und ich komme mit den Imagefunktionen nicht weiter weil das alles etwas undurchsichtig ist. Daher wollte ich den "direkten" Weg gehen. Zudem fand ich es als Herausforderung das umzusetzen, was ist so falsch daran? GIF habe ich gewählt weil es von hause aus indizierte Farbpaletten nutzt und damit meinem Bildformat sehr nahe kommt.

              Die Daten die ich umwandeln möchte liegen einfach als Pixel-Farbindexwerte hintereinander, also 1 Byte pro Pixel. Der Index zeigt auf eine separat vorhandene Farbtabelle in der pro Index ein R,G,B Wert (je 5 Bit pro Farbe) hinterlegt ist.

              Ich habe obigen Code zu Debug-Zwecken nochmal umgeschrieben von direkter Byte-Verarbeitung in Strings (was in PHP immer etwas heikel ist) hin zu Dezimalwerten und Arrays. Was ich nicht verstehe ist, das nur unbekannte Codes in den Output stream gelangen sollen...

              PHP-Code:
              function gif_lzw_data($index_stream)
              {
                  
              $code_stream = array(); # compressed output
                  
              $index_buffer '';

                  
              $lzw_min_code_size 8;
                  
              $color_codes pow(2$lzw_min_code_size);
                  
              $clear_code $color_codes 1;
                  
              $eoi_code $color_codes 2;

                  
              // initialize code table
                  
              $code_table = array();
                  for (
              $i 0$i <= $color_codes$i++)
                  {
                      
              $code_table[] = $i;
                  }
                  
              $code_table[] = $clear_code;
                  
              $code_table[] = $eoi_code;

                  
              $code_stream[] = $clear_code;
                  
              $index_buffer ord(substr($index_stream01));
                  print 
              "DEBUG: first index read from index stream into index buffer: $index_buffer\n";
                  for (
              $i 1$i strlen($index_stream); $i++)
                  {
                      
              $K ord(substr($index_stream$i1));
                      print 
              "DEBUG: next index read from index stream into K: $K\n";
                      
              $lookup $index_buffer ',' $K;
                      print 
              "DEBUG: lookup " $lookup " in code table\n";
                      if (
              in_array($lookup$code_tabletrue))
                      {
                          print 
              "DEBUG: FOUND\n";
                          
              $index_buffer .= $K;
                          
              $K '';
                      }
                      else {
                          print 
              "DEBUG: not found - append to code table\n";
                          
              $code_table[] = $lookup;
                          
              $code_stream[] = $index_buffer;
                          
              $index_buffer $K;
                          
              $K '';
                      }
                  }
                  
              $code_stream[] = $index_buffer# ??? Output code for contents of index buffer
                  
              $code_stream[] = $eoi_code;

                  return 
              implode(","$code_stream);

              Kommentar


              • #8
                Die Daten die ich umwandeln möchte liegen einfach als Pixel-Farbindexwerte hintereinander, also 1 Byte pro Pixel. Der Index zeigt auf eine separat vorhandene Farbtabelle in der pro Index ein R,G,B Wert (je 5 Bit pro Farbe) hinterlegt ist.
                Zeige diese Daten oder Ursprungs-Code, von dem du das Bild erzeugen willst, dann kann man über Lösungen reden, vorher nicht.

                Kommentar


                • #9
                  Zitat von protestix Beitrag anzeigen
                  Zeige diese Daten oder Ursprungs-Code, von dem du das Bild erzeugen willst, dann kann man über Lösungen reden, vorher nicht.
                  Ich finde den Tonfall der da mitschwingt unangemessen. Zudem entscheidest wohl nicht Du ob und was hier diskutiert wird. Wenn Dir das nicht passt, dann lass es halt. Scheinbar hast Du noch nicht verstanden das es hier garnicht um die Daten geht, sondern die Implementation des LZW-Komprimieralgorithmus von Bilddaten im GIF Format. Nichts anderes habe ich angefragt und auch bekundet das ich es aufgrund des Lerneffektes gern umsetzen und verstehen möchte. Und dafür habe ich Hilfe erbeten, aber alles was ich bislang bekomme soll mich von der eigentlichen Aufgabenstellung wegführen... verstehe ich nicht.

                  Wie wärs denn wenn mir mal jemand konkret beim Code hilft?

                  Kommentar


                  • #10
                    Damit man etwas umsetzen kann, muss man Materiial haben. Du hast es, wir nicht.

                    Oft genug liegt der Fehler schon in der Ausgangsbasis der Daten oder diese werden falsch interpretiert. Nur wenn diese Vorliegen kann man auch deinen Code testen und dir sagen hier dran drehen, dort was weglassen, da diese Funktion einbauen usw..

                    Der Tonfall wird schärfer weil du diese Aufforderung schon erhalten und ignoriert hast.
                    Denke bitte daran, du hast ein Problem nicht wir.

                    Kommentar


                    • #11
                      Seufz - Also wenn Du jetzt ernsthaft erwartest das ich Dir so hilfreiche Daten wie "E7 D0 9F 8B 98 4E 7D FA 88 EB D8 B3 6B ..." präsentiere, weil es an Phantasie mangelt sich das selbst auszudenken, dann fürchte ich bist Du ohnehin nicht in der Lage mir bei meinem Problem zu helfen. Von daher wärs für mich okay wenn Du dich ab nun nicht mehr an diesem Thema beteiligst und danke Dir trotzdem für Deine Mühen, denn ich bin ja ein höflicher Mensch.

                      Kommentar


                      • #12
                        Zitat von phreund Beitrag anzeigen
                        Seufz - Also wenn Du jetzt ernsthaft erwartest das ich Dir so hilfreiche Daten wie "E7 D0 9F 8B 98 4E 7D FA 88 EB D8 B3 6B ..." präsentiere, weil es an Phantasie mangelt sich das selbst auszudenken, dann fürchte ich bist Du ohnehin nicht in der Lage mir bei meinem Problem zu helfen. Von daher wärs für mich okay wenn Du dich ab nun nicht mehr an diesem Thema beteiligst und danke Dir trotzdem für Deine Mühen, denn ich bin ja ein höflicher Mensch.
                        Leute öffentlich im Forum zu beleidigen, weil Du nicht klar kommst, ist also höflich? Du verhältst Dich asozial und versuchst dann Deinem Verhalten noch eine Anstrich vorgetäuschter Höflichkeit zu geben. Mehr Arroganz geht ja fast garnicht mehr. In Deinem Texten sind immer die anderen die Dummen. Das Du der eigentliche Trottel bist, fällt Dir garnicht auf.
                        bitcoin.de <- Meine Freelancerwährung

                        Kommentar


                        • #13
                          Solch einen geistigen Diarröh möchte ich garnicht mehr kommentieren, bitte geht woanders User beleidigen.

                          Kommentar


                          • #14
                            Zitat von phreund Beitrag anzeigen
                            Solch einen geistigen Diarröh möchte ich garnicht mehr kommentieren, bitte geht woanders User beiligen!
                            Schreibe es wenigstens richtig....

                            Zur Sache, ich hatte in #6 gefragt, ob du es eher sportlich siehst, das hast du bestätigt und siehst es als Herausforderung, das ist vollkommen OK.

                            Leider ist das Problem nicht so trivial, wie du es darstellst. Irgendwo zwischen 1989 und 1991 hab ich die Erzeugung mal in Assembler geschrieben, das war nicht eben in ein paar Stunden erledigt.

                            Deine wenigen Zeilen Code helfen wenig, das Thema ist auch zu speziell um es in diesem Forum zu lösen.

                            Die Erfahrung habe ich hier selber auch schon gemacht im Bereich 3D Visualisierung. Es sind nur wenige da, die sich in diesem Bereich auskennen und es benötigt viel Zeit, sich in solche Themen einzuarbeiten, das verstehe ich und das solltest du auch verstehen.

                            Ich empfehle: Suche dir den Quellcode zur Erzeugung von .gif Files (Programmiersprache ist egal) und adaptiere den auf PHP, das geht sicher schneller als das Rad komplett neu zu erfinden. Sicher fündig wirst Du in den Quellen von Lazarus.

                            Kommentar


                            • #15
                              Danke, ich fürchte Du hast recht. Ich habe wohl deb groben Fehler begangen mit dem Hinweis auf GIF. Das hätte ich besser weggelassen, denn darauf haben sich dann andere "verbissen". Dabei geht es mir, wie Du sagst, wirklich um die Umsetzung des Algo und den Lerneffekt dabei. Ich denke dennoch das LZW nicht zu kompliziert ist, kein Vergleich mit der Matritzenlogik von 3D Vektoren etc.

                              Vielleicht kommt ja nochmal jemand "vorbei" und überliest den ersten Schmodder, weil er das Thema interessant findet oder wirklich weiss wie es geht. Falls ich es dann doch noch selbst rausfinde und verstehe, sei es auch durch Reverse Engineering von fremden Code, würde ich es hier anfügen.

                              Kommentar

                              Lädt...
                              X