» function imagecreatefrombmp(): Läuft mit allen Bitraten!

CSV Delimiter ermittelnNeuen Thread eröffnenNeue Antwort erstellenRegulärer Ausdruck für Postleitzahl
2>
AutorNachricht
Administrator 

Name: Marc
Geschlecht:
Anmeldedatum: 28.08.2004
Beiträge: 52420
Wohnort: Lohmar


Meine eBay-Auktionen:
16.04.2010, 10:09
zitieren

Meine Version, die bereits alle gängigen 1-, 4-, 8-, 16-, 24- und 32-Bit Bitmaps verarbeiten konnte, wurde durch Fabien Ménager für das Projekt DOMPDF noch perfektioniert.

Nun werden auch komprimierte 4- und 8-bit Bitmaps unterstützt, überflüssige Header ignoriert und zwischen der 555 und 565 Maskierung unterschieden. Ich habe die Version jetzt einfach mal 1.1 getauft:
if ( !function_exists("imagecreatefrombmp") ) {

/**
 * Credit goes to mgutt
 * http://www.programmierer-forum.de/function-imagecreatefrombmp-welche-variante-laeuft-t143137.htm
 * Modified by Fabien Menager to support RGB555 BMP format
 */
function imagecreatefrombmp($filename) {
  // version 1.1
  if (!($fh = fopen($filename, 'rb'))) {
    trigger_error('imagecreatefrombmp: Can not open ' . $filename, E_USER_WARNING);
    return false;
  }
 
  // read file header
  $meta = unpack('vtype/Vfilesize/Vreserved/Voffset', fread($fh, 14));
 
  // check for bitmap
  if ($meta['type'] != 19778) {
    trigger_error('imagecreatefrombmp: ' . $filename . ' is not a bitmap!', E_USER_WARNING);
    return false;
  }
 
  // read image header
  $meta += unpack('Vheadersize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vcolors/Vimportant', fread($fh, 40));
  $bytes_read = 40;
 
  // read additional bitfield header
  if ($meta['compression'] == 3) {
    $meta += unpack('VrMask/VgMask/VbMask', fread($fh, 12));
    $bytes_read += 12;
  }
 
  // set bytes and padding
  $meta['bytes'] = $meta['bits'] / 8;
  $meta['decal'] = 4 - (4 * (($meta['width'] * $meta['bytes'] / 4)- floor($meta['width'] * $meta['bytes'] / 4)));
  if ($meta['decal'] == 4) {
    $meta['decal'] = 0;
  }
 
  // obtain imagesize
  if ($meta['imagesize'] < 1) {
    $meta['imagesize'] = $meta['filesize'] - $meta['offset'];
    // in rare cases filesize is equal to offset so we need to read physical size
    if ($meta['imagesize'] < 1) {
      $meta['imagesize'] = @filesize($filename) - $meta['offset'];
      if ($meta['imagesize'] < 1) {
        trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $filename . '!', E_USER_WARNING);
        return false;
      }
    }
  }
 
  // calculate colors
  $meta['colors'] = !$meta['colors'] ? pow(2, $meta['bits']) : $meta['colors'];
 
  // read color palette
  $palette = array();
  if ($meta['bits'] < 16) {
    $palette = unpack('l' . $meta['colors'], fread($fh, $meta['colors'] * 4));
    // in rare cases the color value is signed
    if ($palette[1] < 0) {
      foreach ($palette as $i => $color) {
        $palette[$i] = $color + 16777216;
      }
    }
  }
 
  // ignore extra bitmap headers
  if ($meta['headersize'] > $bytes_read) {
    fread($fh, $meta['headersize'] - $bytes_read);
  }
 
  // create gd image
  $im = imagecreatetruecolor($meta['width'], $meta['height']);
  $data = fread($fh, $meta['imagesize']);
 
  // uncompress data
  switch ($meta['compression']) {
    case 1: $data = rle8_decode($data, $meta['width']); break;
    case 2: $data = rle4_decode($data, $meta['width']); break;
  }

  $p = 0;
  $vide = chr(0);
  $y = $meta['height'] - 1;
  $error = 'imagecreatefrombmp: ' . $filename . ' has not enough data!';

  // loop through the image data beginning with the lower left corner
  while ($y >= 0) {
    $x = 0;
    while ($x < $meta['width']) {
      switch ($meta['bits']) {
        case 32:
        case 24:
          if (!($part = substr($data, $p, 3 /*$meta['bytes']*/))) {
            trigger_error($error, E_USER_WARNING);
            return $im;
          }
          $color = unpack('V', $part . $vide);
          break;
        case 16:
          if (!($part = substr($data, $p, 2 /*$meta['bytes']*/))) {
            trigger_error($error, E_USER_WARNING);
            return $im;
          }
          $color = unpack('v', $part);

          if (empty($meta['rMask']) || $meta['rMask'] != 0xf800) {
            $color[1] = (($color[1] & 0x7c00) >> 7) * 65536 + (($color[1] & 0x03e0) >> 2) * 256 + (($color[1] & 0x001f) << 3); // 555
          }
          else {
            $color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3); // 565
          }
          break;
        case 8:
          $color = unpack('n', $vide . substr($data, $p, 1));
          $color[1] = $palette[ $color[1] + 1 ];
          break;
        case 4:
          $color = unpack('n', $vide . substr($data, floor($p), 1));
          $color[1] = ($p * 2) % 2 == 0 ? $color[1] >> 4 : $color[1] & 0x0F;
          $color[1] = $palette[ $color[1] + 1 ];
          break;
        case 1:
          $color = unpack('n', $vide . substr($data, floor($p), 1));
          switch (($p * 8) % 8) {
            case 0: $color[1] =  $color[1] >> 7; break;
            case 1: $color[1] = ($color[1] & 0x40) >> 6; break;
            case 2: $color[1] = ($color[1] & 0x20) >> 5; break;
            case 3: $color[1] = ($color[1] & 0x10) >> 4; break;
            case 4: $color[1] = ($color[1] & 0x8 ) >> 3; break;
            case 5: $color[1] = ($color[1] & 0x4 ) >> 2; break;
            case 6: $color[1] = ($color[1] & 0x2 ) >> 1; break;
            case 7: $color[1] = ($color[1] & 0x1 );      break;
          }
          $color[1] = $palette[ $color[1] + 1 ];
          break;
        default:
          trigger_error('imagecreatefrombmp: ' . $filename . ' has ' . $meta['bits'] . ' bits and this is not supported!', E_USER_WARNING);
          return false;
      }
      imagesetpixel($im, $x, $y, $color[1]);
      $x++;
      $p += $meta['bytes'];
    }
    $y--;
    $p += $meta['decal'];
  }
  fclose($fh);
  return $im;
}
}

Dadurch werden noch diese Funktionen notwendig:
/** 
 * Decoder for RLE8 compression in windows bitmaps
 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
 *
 * @param string  $str   Data to decode
 * @param integer $width Image width
 *
 * @return string
 */
function rle8_decode ($str, $width){
  $lineWidth = $width + (3 - ($width-1) % 4);
  $out = '';
  $cnt = strlen($str);
 
  for ($i = 0; $i <$cnt; $i++) {
    $o = ord($str[$i]);
    switch ($o){
      case 0: # ESCAPE
        $i++;
        switch (ord($str[$i])){
          case 0: # NEW LINE
            $padCnt = $lineWidth - strlen($out)%$lineWidth;
            if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line
            break;
          case 1: # END OF FILE
            $padCnt = $lineWidth - strlen($out)%$lineWidth;
            if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line
            break 3;
          case 2: # DELTA
            $i += 2;
            break;
          default: # ABSOLUTE MODE
            $num = ord($str[$i]);
            for ($j = 0; $j < $num; $j++)
              $out .= $str[++$i];
            if ($num % 2) $i++;
        }
      break;
      default:
      $out .= str_repeat($str[++$i], $o);
    }
  }
  return $out;
}
/**
 * Decoder for RLE4 compression in windows bitmaps
 * see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
 *
 * @param string  $str   Data to decode
 * @param integer $width Image width
 *
 * @return string
 */
function rle4_decode ($str, $width) {
  $w = floor($width/2) + ($width % 2);
  $lineWidth = $w + (3 - ( ($width-1) / 2) % 4);   
  $pixels = array();
  $cnt = strlen($str);
  $c = 0;
 
  for ($i = 0; $i < $cnt; $i++) {
    $o = ord($str[$i]);
    switch ($o) {
      case 0: # ESCAPE
        $i++;
        switch (ord($str[$i])){
          case 0: # NEW LINE
            while (count($pixels)%$lineWidth != 0) {
              $pixels[] = 0;
            }
            break;
          case 1: # END OF FILE
            while (count($pixels)%$lineWidth != 0) {
              $pixels[] = 0;
            }
            break 3;
          case 2: # DELTA
            $i += 2;
            break;
          default: # ABSOLUTE MODE
            $num = ord($str[$i]);
            for ($j = 0; $j < $num; $j++) {
              if ($j%2 == 0) {
                $c = ord($str[++$i]);
                $pixels[] = ($c & 240)>>4;
              }
              else {
                $pixels[] = $c & 15;
              }
            }
           
            if ($num % 2 == 0) {
              $i++;
            }
       }
       break;
      default:
        $c = ord($str[++$i]);
        for ($j = 0; $j < $o; $j++) {
          $pixels[] = ($j%2==0 ? ($c & 240)>>4 : $c & 15);
        }
    }
  }
 
  $out = '';
  if (count($pixels)%2) {
    $pixels[] = 0;
  }
 
  $cnt = count($pixels)/2;
 
  for ($i = 0; $i < $cnt; $i++) {
    $out .= chr(16*$pixels[2*$i] + $pixels[2*$i+1]);
  }
   
  return $out;
}


Die Basis bildete damals wie gesagt die Funktion von DHKold, der diese bei php.net veröffentlicht hatte.

Damals suchte ich selbst nach dieser Funktion. Zur Vollständigkeit hier die Beiträge als ich mit der Recherche begann:
ZitatIch habe ca. 1.000 durch Nutzer unserer Community hochgeladene Bitmaps zum Test herangezogen.

Diese Funktion geht nicht:
http://printf.ru/wiki/imagecreatefrombmp

Diese auch nicht:
http://snipplr.com/view/24283/imagecreatefrombmp/

Sinnfrei, weil die includete "function_imagecreatefrombmp.php" fehlt:
http://www.php-code.eu/code/Function-ImageCreateFromBMP-169.html

Weitere Tests laufen..



Verfasst am: 16.04.2010, 14:34
zitieren

Funktioniert nicht (werden falsch ausgelesen und dazu läuft der RAM voll):
http://www.php.net/manual/de/function.imagecreatefromwbmp.php#83119

Verfasst am: 16.04.2010, 14:50
zitieren


Verfasst am: 16.04.2010, 14:55
zitieren

Getestet mit den Bugfixes in späteren Kommentaren:
http://www.php.net/manual/de/function.imagecreate.php#53879

Resultat:
Noch nicht ganz perfekt.

Ich habe das noch etwas korrigiert, da die Bugfixes nicht korrekt waren und zu Farbfehlern bei 16 Bit Bitmaps führten.

Weiterhin habe ich den Code optimiert und eine Bedingung für 16 Bit Bilder realisiert, die auch eine Palette besitzen.

Aktuell hänge ich bei einigen wenigen Bildern fest, die nicht korrekt umgerechnet werden. Laut Header haben die ebenfalls 16 Bit, aber nach ca. 50% bricht die Umrechnung ab. Keine Ahnung warum.

Die Funktion unterstützt auch kein 32 Bit. Daher suche ich erstmal weiter.

Verfasst am: 16.04.2010, 15:04
zitieren

Soll bei 32 Bit gehen, funktionierte bei mir aber nur mit 8 Bit:
http://bytes.com/topic/php/answers/6631-bmp-gd-then-jpg-32-bits

Verfasst am: 16.04.2010, 15:12
zitieren

Die Funktion hat fast genau den gleichen Fehler wie die von mir zuvor korrigierte von php.net:
http://bytes.com/topic/php/answers/4399-imagecreatefrombmp (Den Link hatte ich hier gefunden)

Bei bestimmten 16 Bit Bildern gibts Probleme. Allerdings bei ein paar mehr als zuvor.

Es resultiert diese Fehlermeldung:
ZitatWarning: imagecreatefromgd() [function.imagecreatefromgd]: '/tmp/GDZs5PSQ' is not a valid GD file in /www/htdocs/xyz on line 123

Ich vermute mal fast, dass die in der Version komplett ignoriert werden und daher der Fehler auftaucht. Ich mach mir mal die Mühe und formatiere den Code. Mal sehen ob ich was finde.

 1x  bearbeitet

Verfasst am: 16.04.2010, 15:39
zitieren

Ok die Funktion kann allgemein nicht mit 16 Bit Bildern umgehen. Mal sehen ob ich sie erweitern kann.

Verfasst am: 16.04.2010, 15:52
zitieren

Noch habe ich nichts herausfinden können. Aber dafür habe ich schon mal die 32-Bit Bedingung von hier eingebaut.

Ich muss gleich mal schauen, ob ich überhaupt 32 Bit Bitmaps zum Testen da habe.

Aber bis dahin erstmal weiter mit 16 Bit. Hier hatte schon jemand erfolglos danach gefragt.

Verfasst am: 16.04.2010, 16:00
zitieren

An die 16 Bit Lösung hat sich hier schon mal jemand rangetraut:
http://stackoverflow.com/questions/1586094/convert-bitmap-files-into-jpeg-using-the-gd-library-in-php/1586107#1586107

Aber die Variante habe ich getestet und ich erhalte wie in dem Kommentar geschildert ebenfalls ein grünes Bild als Resultat.

Verfasst am: 16.04.2010, 16:07
zitieren

Ich bin bei der Suche hier drüber gestolpert:
http://www.phpsources.org/scripts120-PHP.htm

Funktioniert aber mit gar keiner Bitrate bzw. alle Bilder werden diagonal und schwarz / weiß ausgegeben ;)
pn email
Gast 
02.03.2015, 21:58
zitieren

Mach mit!

Wenn Dir die Beiträge zum Thread "function imagecreatefrombmp(): Läuft mit allen Bitraten!" gefallen haben oder Du noch Fragen hast oder Ergänzungen machen möchtest, solltest Du Dich gleich bei uns anmelden:



Registrierte Mitglieder genießen die folgenden Vorteile:
✔ kostenlose Mitgliedschaft
keine Werbung
✔ direkter Austausch mit Gleichgesinnten
✔ neue Fragen stellen oder Diskussionen starten
✔ schnelle Hilfe bei Problemen
✔ Bilder und Videos hochladen
✔ und vieles mehr...


Neuen Thread eröffnenNeue Antwort erstellen
2>
Ähnliche BeiträgeRe:
Letzter Beitrag
mkfile function
Hi, diese Funktion erstellt bei Bedarf eine Datei. function mkfile&#40;$filename, $data='', $chmod=0644&#41; &#123; $h = @fopen&#40;$filename, 'w'&#41;; @fwrite&#40;$h,...
[PHP]von mgutt
0
1.362
20.09.2009, 13:25
mgutt
The Pursuit of Function
He Leute ich denke dieses Material gehört mit zu den besten Docu´s die erzählen was JDM eigentlich ist! Ich kann nur sagen es lohnt sich es zu besorgen, nachdem man diese Docu geguckt hat versteht man JDM und den Lebenstil JDM. Ich kann nur sagen ...
von Smooth587
2
329
21.01.2008, 22:29
Smooth587
Warning: mysql_connect() [function.mysql-connect]: Can't con
Ich brauche dringend hilfe. auf [URL=http://imp-rom.wdpt.de/]http://imp-rom.wdpt.de[/URL] kann ich nicht weiterarbeiten, weil die MySQL-Verbindung nicht klappt. Ich hab alles versucht, aber die Daten stimmen und ich weiß nicht, was ich jetzt noch tun...
[Allgemein]von mox9.imp-rom
3
1.977
03.09.2009, 12:19
mox9.imp-rom
Erfahrungen mit Gewindefahrwerk Function & Form Type 1 und Type 2
Hab die SuFu benutzt aber nichts gefunden. Ich bin am überlegen mir so ein Gewindefahrwerk schicken zu lassen. Hat jemand von euch schon mal ein Function & Form Type 1 oder Type 2 in einem ed9 gefahren? Mit was ist das Vergleichbar? Ist es...
von Nudel mid Hack
11
728
05.01.2014, 14:57
SureX
ED9 Daily - form<function - "CRX zero"
Hallo miteinander, manche sollten mich schon aus dem del Sol Bereich kennen, ich bin der Kevin und seit nun fast 4 Jahren Hondaholic. Nach nunmehr 3 Jahren del Sol hab ich mir durch einen glücklichen Zufall den Traumwagen No. 2 erfüllt: einen...
von Onkel Satan
7
576
12.05.2015, 20:12
Onkel Satan
wünsche allen
wünsche allen MaXReVer´n heut abend viel...
von Kolbenring
25
1.251
02.11.2006, 18:49
eRX
ch1 zündausetzer in allen zylindern
Mahlzeit leute hab da ein problem mit meim ch1 motorkontrllleuchte leuchtet hab fehlerausgelesen obd gerät sagt zündaussetzer bei allen zylindern was kan das sein was muss ich da als erstes prüfen?? Bin über jede Antwort glücklich...
von ciwich
4
230
17.11.2014, 08:19
Headshot91
allen ein schönen Männertag
An alle maxrev Männer. Ich wünsche euch einen schönen und flüssigen Männertag;) und lasst die autos danach stehen;) viel...
von hatebreed91
2
143
17.05.2012, 17:36
Andrüha1HGEJ2
US Blinker glimmen an allen Blinkern
Hi, hab grad die us style blinker module drinne... die frontblinker glimmen mit abblendlicht.. einmal habe ich es hinbekommen gehabt das die komplette blinkanlage geglimmt hat.. wie ich dies gemacht habe weiss ich nicht mehr.. kann mir da einer...
von semih37
2
286
31.01.2011, 12:03
RGT
Unterschied zwischen allen Motoren ??
Hey,worin liegt der unterschied zwischen den b,-d,-k,-h.-etc. motoren,und dem y7,y8,z6 und was da alles giebt,und was bedeutet dies alles... Bitte helft mir-bin sehr an honda interessiert Danke im vor hinein Mfg...
von EJ6_JUNKEY_
5
270
29.11.2010, 22:16
Der_Ronny
© 2004 - 2024 www.programmierer-forum.de | Communities | Impressum |