» 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: 50777
Chats: 11159
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...

Zu function imagecreatefrombmp und programmierer foren findest Du weitere passende Themen in der Suche.


Neuen Thread eröffnenNeue Antwort erstellen
2>
Ähnliche BeiträgeRe:
Letzter Beitrag
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
470
05.01.2014, 14:57
SureX
Komplette Auspuffanlage mit allen Katalysatoren
Hi Jungs :) Ich bräuchte mal einen link wo die komplette Auspuffanlage mit beiden Katalysatoren und den ganzen Verbindungen und dichtungen abgebildet sind. Danke Gruß...
von crysis84
3
237
03.09.2013, 22:28
flip
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
975
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
270
21.01.2008, 22:29
Smooth587
Liste mit allen Felgen und deren Gewicht
http://www.wheelweights.net/ Hier ist eine Liste mit allen Felgen und deren Gewicht finde ich ganz...
von ej2vtec
0
284
29.08.2013, 03:09
ej2vtec
Burnout mit meine Prelude sollte bei allen gehen
Ich habe mal meine alten Sommerreifen verheitzt, komischer weisse läuft das Auto nach dem Burnout besser. Ich empfehle euch das nicht nach zumachen denn nach einer Woche stinkt es immernoch nach Gummi im Innenraum. Einmal sieht man im video dass der...
von 36Chamber
14
1.571
23.02.2006, 21:51
Metalass
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.763
03.09.2009, 12:19
mox9.imp-rom
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
469
12.05.2015, 20:12
Onkel Satan
wünsche allen
wünsche allen MaXReVer´n heut abend viel...
von Kolbenring
25
1.130
02.11.2006, 18:49
eRX
hiiilfeeee.... kondenswasser in allen 4 scheinwerfern.....
ja wie man schon am thema erkennen kann hab ich nach m autowasche am clean-park wasser in allen 4 scheinwerfern..... :cry: :cry: :cry: wie krig ich des da wieder raus, bzw. wie mach ich des wieder dicht??? gibbet da so dichtungen oder so...
von narcotic
8
407
04.05.2006, 14:19
narcotic
© 2004 - 2016 www.programmierer-forum.de | Communities | Impressum |