How to grayscale a gif using bit-swapping

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Lars Erik Bryld

    How to grayscale a gif using bit-swapping

    Hello group

    I am trying to convert a (supposedly) working python script into php.
    The script reads a colour gif-picture and produces a greyscale copy of
    it.

    The method is to first copy the gif header, then establish the size of
    the colour palette, then do a simple averaging of each colour byte
    triplet into a grayscale equivalent, and finally to copy the remaining
    part of the gif file unaltered over into the new file. I believe, it's
    the last procedure that goes wrong, partly because of my inability to
    understand the file manipulation issues.


    The original Python script:

    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(g ray))
    o.write(f.read( ))


    My feeble and as yet non-functional PHP translation:

    $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, 999999999999999 99999);
    fwrite($fo, $rest);

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




    I hope some kind spirit will point out any blatant errors in my use of
    the functions above. I only get small 2-300 byte long output files
    regardless of input file size.


    --
    Regards
    Lars Erik Bryld
  • Kimmo Laine

    #2
    Re: How to grayscale a gif using bit-swapping

    "Lars Erik Bryld" <larserik@dadln et.invalidwrote in message
    news:31ddofla5n 3x.dlg@lebryld. fqdn...
    Hello group
    >
    I am trying to convert a (supposedly) working python script into php.
    The script reads a colour gif-picture and produces a greyscale copy of
    it.
    >
    The method is to first copy the gif header, then establish the size of
    the colour palette, then do a simple averaging of each colour byte
    triplet into a grayscale equivalent, and finally to copy the remaining
    part of the gif file unaltered over into the new file. I believe, it's
    the last procedure that goes wrong, partly because of my inability to
    understand the file manipulation issues.
    >
    >
    The original Python script:
    >
    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(g ray))
    o.write(f.read( ))
    >
    >
    My feeble and as yet non-functional PHP translation:
    >
    $fi = fopen("in.gif", 'r');
    $fo = fopen("out.gif" , 'w');
    >
    $header = fread($fi, 13);
    fwrite($fo, $header);
    >
    $l = (1 << (ord($header[10]) & 7) + 1);
    Have you tested that this actually gives the correct value? Just that it
    looks a bit.. hmm.. error-bound? :) Although it does seem to be the same as
    the original...
    >
    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));
    If the goal here is to write the same value three times (for r,g,b) you want
    str_repeat(chr( $gray),3). 3*chr($gray) will give you unexpected results.
    }
    >
    $rest = fread($fi, 999999999999999 99999);
    fwrite($fo, $rest);
    >
    fclose($fi);
    fclose($fo);
    >


    --
    "Ohjelmoija on organismi joka muuttaa kofeiinia koodiksi" - lpk
    http://outolempi.net/ahdistus/ - Satunnaisesti päivittyvä nettisarjis
    spam@outolempi. net | rot13(xvzzb@bhg byrzcv.arg)


    Comment

    • C.

      #3
      Re: How to grayscale a gif using bit-swapping

      On 21 Mar, 18:27, Lars Erik Bryld <larse...@dadln et.invalidwrote :
      >
      I am trying to convert a (supposedly) working python script into php.
      The script reads a colour gif-picture and produces a greyscale copy of
      it.
      >
      <snip>

      It would be safer to use GD. There's even an example of how to do this
      at http://www.php.net/manual/en/function.imagecolorset.php

      (FWIW, both the example above and your own code use an averaging
      method to determine the grey scale; while color models vary, it might
      be more approriate to measure the size of the orthognal vectors -
      (integer)(sqrt( $red*$red + $green*$green + $blue*$blue)*0. 5769)
      )

      C.

      Comment

      • Lars Erik Bryld

        #4
        Re: How to grayscale a gif using bit-swapping

        Scripsit Kimmo Laine:
        >$l = (1 << (ord($header[10]) & 7) + 1);
        >
        Have you tested that this actually gives the correct value? Just
        that it looks a bit.. hmm.. error-bound? :) Although it does seem
        to be the same as the original...
        Tested it, at it seems to work. Most GIFS produce the value 256, and a
        B/W GIF produces 2 as it should.
        If the goal here is to write the same value three times (for r,g,b)
        you want str_repeat(chr( $gray),3). 3*chr($gray) will give you
        unexpected results.

        Tried yoru suggestion, but same result, alas.
        >$rest = fread($fi, 999999999999999 99999);
        >fwrite($fo, $rest);
        >>
        >fclose($fi);
        >fclose($fo);
        This is what I suspect is not doing what I thought it would.


        --
        Med venlig hilsen
        Lars Erik Bryld

        Comment

        • Lars Erik Bryld

          #5
          Re: How to grayscale a gif using bit-swapping

          Scripsit C.:
          It would be safer to use GD. There's even an example of how to do
          this at http://www.php.net/manual/en/function.imagecolorset.php
          For what it's worth, I'd rather find out why my own little script
          doesn't do as intended and thus possibly get a little smarter in the
          process of tweaking it into doing what I want.

          I'm not really trying to greyscale images, I'm trying to learn gif
          palette manipulation.

          --
          Regards
          Lars Erik Bryldi

          Comment

          • Kimmo Laine

            #6
            Re: How to grayscale a gif using bit-swapping

            spam@outolempi. net | rot13(xvzzb@bhg byrzcv.arg)
            "Lars Erik Bryld" <larserik@dadln et.invalidwrote in message
            news:ifoxx8z4ay e5.dlg@lebryld. fqdn...
            Scripsit Kimmo Laine:
            >
            >>$l = (1 << (ord($header[10]) & 7) + 1);
            >>
            >Have you tested that this actually gives the correct value? Just
            >that it looks a bit.. hmm.. error-bound? :) Although it does seem
            >to be the same as the original...
            >
            Tested it, at it seems to work. Most GIFS produce the value 256, and a
            B/W GIF produces 2 as it should.
            >
            >If the goal here is to write the same value three times (for r,g,b)
            >you want str_repeat(chr( $gray),3). 3*chr($gray) will give you
            >unexpected results.
            >
            >
            Tried yoru suggestion, but same result, alas.
            >
            >>$rest = fread($fi, 999999999999999 99999);
            >>fwrite($fo, $rest);
            >>>
            >>fclose($fi) ;
            >>fclose($fo) ;
            >
            This is what I suspect is not doing what I thought it would.
            >
            Try this instead:
            while(!feof($fi ) ){
            fwrite($fo, fread($fi, 256));
            }


            --
            "Ohjelmoija on organismi joka muuttaa kofeiinia koodiksi" - lpk
            http://outolempi.net/ahdistus/ - Satunnaisesti päivittyvä nettisarjis


            Comment

            • Lars Erik Bryld

              #7
              Re: How to grayscale a gif using bit-swapping

              Scripsit Kimmo Laine:
              >>>$rest = fread($fi, 999999999999999 99999);
              >>>fwrite($fo , $rest);
              >>>>
              >>>fclose($fi );
              >>>fclose($fo );
              >>
              >This is what I suspect is not doing what I thought it would.
              >>
              >
              Try this instead:
              while(!feof($fi ) ){
              fwrite($fo, fread($fi, 256));
              }
              Worked like a charm, thanks. Turned out that PHP balked at the
              9999999999999 part.

              --
              Med venlig hilsen
              Lars Erik Bryld

              Comment

              Working...