Raw Bild rendern

  • PHP

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Raw Bild rendern

    Schon seit etwas längeren habe ich ein Problem, dass sich einfach nicht lösen lassen will.
    Ich versuche ganz ohne Erweiterungen oder externen Programmen wie Imagic ein Raw bild zu convertieren.

    Mir ist natürlich klar, dass meine methode relativ langsam und alles andere als performant ist. Unversucht wollte ich es dennoch nicht lassen.
    Also: die zu konvertieren raw bilder haben alle samt 4 kanäle (B G R A) sind 8bit und interleaved. Sollte nicht so schwer sein, dachte ich mir, und habe es folgender maßen angegriffen:
    Spoiler anzeigen

    PHP-Quellcode

    1. <?php
    2. error_reporting(E_ALL | E_STRICT);
    3. class raw {
    4. public $fortsrt=0;
    5. private $raw_data;
    6. public function __construct($data) {
    7. $this->raw_data=$data;
    8. }
    9. private function read_byte() {
    10. $ret=ord(substr($this->raw_data,$this->fortsrt,1));
    11. $this->fortsrt++;
    12. if (isset($ret)) {
    13. return $ret;
    14. } else {
    15. return 0;
    16. }
    17. }
    18. private function get_size() {
    19. return strlen($this->raw_data);
    20. }
    21. public function read() {
    22. $size=$this->get_size();
    23. $pos=0;
    24. for($a=0;$a<=$size;$a++){
    25. switch ($a%4) {
    26. case (0) : $return['b'][$pos]=$this->read_byte(); break;
    27. case (1) : $return['g'][$pos]=$this->read_byte(); break;
    28. case (2) : $return['r'][$pos]=$this->read_byte(); break;
    29. case (3) : $return['a'][$pos]=$this->read_byte(); $pos++; break;
    30. }
    31. }
    32. return $return;
    33. }
    34. public function write_png($input, $width, $height) {
    35. if ($width*$height*4 != $this->get_size()) {return -1; }
    36. $im = imagecreatetruecolor($width, $height);
    37. for ($x=0;$x<$width;$x++) {
    38. for ($y=0;$y<$height;$y++) {
    39. $pos=$x*$y;
    40. $color = imagecolorallocate($im,
    41. $input['r'][$pos],
    42. $input['g'][$pos],
    43. $input['b'][$pos]);
    44. imagefilledrectangle($im,$x,$y,$x+1,$y+1,$color);
    45. }
    46. }
    47. return $im;
    48. }
    49. }
    50. $file=fopen("output/img/sprite_sprite0/sub.0.raw","r");
    51. $str=fread($file,filesize("output/img/sprite_sprite0/sub.0.raw"));
    52. fclose($file);
    53. $raw = new raw($str);
    54. $data = $raw->read();
    55. $image = $raw -> write_png($data,16,16);
    56. header ('Content-type: image/png');
    57. imagepng($image);
    58. imagedestroy($image);
    59. //print_r($data);
    60. ?>
    Alles anzeigen
    Und hiermit ordentlicher formatierung

    Dabei wurde dieses 16x16 px bild zu diesem hier
    Vllt sieht man es hier besser: wurde zu

    Ich habe nach längerem googlen etwas in Java gefunden. Und lustiger weise wars IsmAvatar (dem macher von LGM) der dieses Problem hatte. Ich habe die source von LGM durchstöbert, und dann dies gefunden: pastie.org/883077 (java halt)
    Bei ihm funktioniert es. Leider ist mir die java syntax überhaubt nicht vertraut, kann also kaum herrauslesen was er macht und was ich nicht mache.
    Ich habe ne vermutung, dass es was damit zu tun hat, dass das Raw bild Interleavedist. Und wenn ja, um welchen faktor wurde Interleaved. Und wie mache ich das dann?

    Nachdem ich schon die letzten wochen den Chat mit meinem Problem genervt habe, dort allerdings keiner ne antwort auf die einfachsten Fragen hatte, hoffe ich, dass sich hier jemand findet, der meinen Fehler aufdecken kann.

    MfG SDX
  • Also wenn ich den Code jetzt richtig nachvollzogen habe, dann könnte ich mir gut vorstellen, dass der Fehler in Zeile 42 liegt. So wie du dort $pos berechnest kann ich mir auch sehr gut diese Ringbildung erklären. Wie kommst du auf die Berechnung? Also wenn ich mal davon ausgehe, dass in dem Raw-Format die Pixel zeilenweise gespeichert werden, dann sollte Zeile 42 eher lauten

    PHP-Quellcode

    1. $pos = $y*$width+$x;

    ansonsten probier mal

    PHP-Quellcode

    1. $pos = $x*$height+$y;
  • Vielen dank, funktioniert jetzt super.
    0.02 sek für ein 16x16 px bild
    nachdem ein 640x480px bild 1200 mal so groß ist, konnte ich mir ausrechnen, dass es dann 24 sec dauern wird.. wurden dann schlappe 24.599 sekunden.

    Ich stelle das thema mal auf erledigt, aber falls jemand noch ideen hat, wie man es optimieren kann, werde ich ihm nicht böse wenn er seine idee postet ;)

    MfG SDX