Jump to content
  • 0

Php and Palette(.pal)


Question

Posted (edited)

Hi all, i'm brasilian then sorry my english.

I'm wrinting a php code to read spr files and build char image, but how can i make code read pal files and apply this palette to a (head)hair?

Please i'm trying to do this a long time.

If you can help me or know where can i find a code, it will be helpfull.

Thanks for all!

Att,

CaioVictor.

EDIT 01 =======>

I'm searching in google and i can't find anything to help me with this

Edited by CaioVictor

13 answers to this question

Recommended Posts

Posted

Palette contain 1024 bytes, so basically 256 * rgba values (when alpha isn't used).

Sprite contain palette indexes (and in some cases, some raw images).

And one (default) palette is also contain in the end of a sprite file, so if you can display a sprite without loading an extra .pal file you should be able to load a .pal file (it's the same thing).

So basically:

// Loading palette
$pal_data = fread( $fp_pal, 1024 );

// Allocate palettes
$palette  = array();
for ( $i=0, $j=0; $i<256; $i++, $j+=4 )
{
   $palette[ $i ] = imagecolorallocate(
       ord( $pal_data[$j+0] ),
       ord( $pal_data[$j+1] ),
       ord( $pal_data[$j+2] )
    );
}

// Display a pixel : ($spr_index)
imagesetpixel( $img, $x, $y, $palette[ $spr_index ] );

Posted

Ok, let me see...

this is my code to open spr file:

function readSprite($sprite){
$this->spr = fopen($sprite, "rb");
$this->sHeader = unpack('H4ident/Sversion/Snum_pal/Snum_rgba',fread($this->spr, 0x08));
$this->sSize = filesize($sprite);
$this->numberFrames = $this->sHeader['num_pal']+$this->sHeader['num_rgba'];
$this->sVersion = dechex($this->sHeader['version']);
$this->sVersion = preg_replace('{([0-9])(.*?)([0-9])}', '$1.$2', $this->sVersion);
if($this->sHeader['num_pal'] > 0) {
 for($i=0;$i<$this->sHeader['num_pal'];$i++) {
  $this->frames[$i] = unpack('Swidth/Sheight/Sdata_length', fread($this->spr, 0x06)) + array('offset'=>ftell($this->spr));
  fseek($this->spr, $this->frames[$i]['data_length'], SEEK_CUR);
 }
} elseif($this->sHeader['num_rgba'] > 0) {
 for($i=0;$i<$this->sHeader['num_rgba'];$i++) {
  $this->frames[$i] = unpack('Swidth/Sheight', fread($this->spr, 0x04));
  $this->frames[$i]['data_length'] = $this->frames[$i]['width'] * $this->frames[$i]['height'] * 4;
  $this->frames[$i]['offset'] = ftell($this->spr);
  fseek($this->spr, $this->frames[$i]['data_length'], SEEK_CUR);
 }
}
$this->frames['PAL'] = ftell($this->spr);
$i=0;
$a=0;
while(!feof($this->spr)){
 $color = @unpack('Ccolor', fread($this->spr, 0x01));
 if(dechex($a) < 100) {
  $this->palette[$a] .= $color['color'].":";
 }
 $i++;
 if($i >= 4) {
  $this->palette[$a] = rtrim($this->palette[$a],":");
  $a++;
  $i=0;
 }
}
}

Can you show me what is tha same that $spr_index?

Posted

Well, each frames in the sprite have a data ( the data start to $this->frames[<index>]['offset'] and end to ($this->frames[<index>]['offset'] + $this->frames[<index>]['data_length'] ).

Each bytes of this data represent $spr_index.

Posted

Thanks for answer KeyWorld!

The code will be something like this?

for($i=0;$i<$this->sHeader['num_pal'];$i++){
   $this->frames[$i] = unpack('Swidth/Sheight/Sdata_length', fread($this->spr, 0x06)) + array('offset'=>ftell($this->spr));
   fseek($this->spr, $this->frames[$i]['data_length'], SEEK_CUR);

   for($c = 0; $c < $this->frames[$i]['data_length']; $c++){
  	 $spr_index = ???
   }

}

Posted
 // When loading frames:
for( $i=0; $i<$this->sHeader['num_pal']; $i++ )
{
   $this->frames[$i] = unpack('Swidth/Sheight/', fread($this->spr, 0x04));
   extract( unpack('Ssize', fread($this->spr,0x02) ) );
   $this->frames[$i]['data'] = fread( $this->spr, $size );
}



// When you want to draw a frame

$frame  = $this->frames[$frame]; // $frame is the frame you want to render
$width  = $frame['width'];
$height = $frame['height'];
$data   = $frame['data'];
$img    = imagecreatetruecolor( $width, $height );


// Allocate palette
$pal = array();
for ( $i=0, $j=4; $i<256; ++$i, ++$j )
   $pal[$i] = imagecolorallocate(
       $img,
       ord($this->palette[$j++]),
       ord($this->palette[$j++]),
       ord($this->palette[$j++])
   );

// Render image
for ( $i=0; $i < $width * $height; ++$i )
{
   imagesetpixel( $img, $i % $width, $i/$width | 0, $pal[ ord($data[$i]) ] );
}

imagepng( $img );

  • Upvote 3
Posted

Seems like you have a debug in your php file (echo) that print 308892.

Once you remove this line, add a header('Content-type:image/gif'); before the imagegif() (or before the whole code).

  • Upvote 1
Posted (edited)

EDIT 3: Ignore this post, I'm done. :3 Thanks for your help!

Omfg. It worked but there's still these „t*4üÒÜÜ’„¼rlT>TüâÌŒfl¬¦Ä̶¬œV thingies and it only shows the first frame 45 times lol.

So now I tried to copy your code but it shows black D: for 45 times.

Edit: Alright, so the frames are now showing 8D But I want to remove the gibberish text. How to do it?

http://i.imgur.com/VrZIQ.jpg << image is too big and disturbing lol.

Edit 2: Okay so I temporarily fixed it by making another file and making a loop.

Edited by kenshn111

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...