我在this code工作,并考虑到“修复”它为32位的评论,但似乎仍然无法正常工作.我很确定它与TGA descriptor有关.这将使用位0-3作为alpha通道深度,对于32位总是为8,并且代码没有考虑到这一点.
我试图了解如何使用this C code作为指导将它拼凑在一起,但没有运气.
似乎一旦你考虑到长度为4的像素(根据评论中的补丁),他的dwordize只占4个字节中的3个,第4个字节是我认为的alpha位.
我试过更改功能
function dwordize($str)
{
$a = ord($str[0]);
$b = ord($str[1]);
$c = ord($str[2]);
return $c*256*256 + $b*256 + $a;
}
至
function dwordize($str)
{
$a = ord($str[0]);
$b = ord($str[1]);
$c = ord($str[2]);
$d = ord($str[3]);
return $d*256*256*256 + $c*256*256 + $b*256 + $a;
}
哪个没用,然后试了
function dwordize($str)
{
$a = ord($str[0]);
$b = ord($str[1]);
$c = ord($str[2]);
$d = ord($str[3]);
return $c*256*256 + $b*256 + $a + $d*256*256*256;
}
所有这些我试图从像RBGA到BGRA的C代码,然后索引都很奇怪.我真的不明白C代码足以将它应用于PHP代码.
我也找到了this site这可能会有所帮助,我现在正在读它,如果我拿出任何东西我会更新. 解决方法: 我找到了你的解决方案.在RLE解码函数中需要进行缺少调整以支持32位像素格式:即:AARRGGBB
首先,我们需要按照评论中的建议绕过库的颜色深度检查,因此我们将检查更改为第99行
if ($header['pixel_size'] != 24 && $header['pixel_size'] != 32) {
die('Unsupported TGA color depth');
}
然后我们需要更改一些与颜色深度相关的变量.它们中的大多数将用于数据格式化,因此无论颜色深度如何,我们都需要它们具有正确的值. 那就是:
第104行:$bytes = $header [‘pixel_size’] / 8;
第117行:$size = $header [‘width’] * $header [‘height’] * $bytes;
第154行:$pixels = str_split($data,$bytes);
并删除第153行:$num_bytes = $header [‘pixel_size’] / 8;我们不再需要它了.
然后我们需要rle_decode()函数来知道像素格式的大小,因此当我们调用它时,我们需要传递这个参数,因此我们需要更改以下行:
第141行:$data = rle_decode($data,$size,$bytes);
因此函数原型变为:
第9行:函数rle_decode($data,$datalen,$pixel_size)
现在你可以看到这个函数有多个3个幻数(即:for($j = 0; $j< 3 * $value; $j)在29行). 所有这些必须由像素大小参数替换. (3位为24位,4位为32位)
此外,有时在创建像素时它只会写入3个字节而不是4个字节,所以我们也必须调整它.
所以最后这给了我们以下算法:
function rle_decode($data, $datalen, $pixel_size)
{
$len = strlen($data);
$out = '';
$i = 0;
$k = 0;
while ($i<$len)
{
dec_bits(ord($data[$i]), $type, $value);
if ($k >= $datalen)
{
break;
}
$i++;
if ($type == 0) //raw
{
for ($j=0; $j<$pixel_size*$value; $j++)
{
$out .= $data[$j+$i];
$k++;
}
$i += $value*$pixel_size;
}
else //rle
{
for ($j=0; $j<$value; $j++)
{
$out .= $data[$i] . $data[$i+1] . $data[$i+2];
if ($pixel_size == 4) $out .= $data[$i+3];
$k++;
}
$i += $pixel_size;
}
}
return $out;
}
就是这样,你现在可以完美地转换你的TGA图像.我给你完整的tga.PHP代码,所以你可以直接粘贴它并自己测试它:
<?PHP
// Author: de77
// Licence: MIT
// First-version: 9.02.2010
// Version: 24.08.2010
// http://de77.com
function rle_decode($data, $datalen, $pixel_size)
{
$len = strlen($data);
$out = '';
$i = 0;
$k = 0;
while ($i<$len)
{
dec_bits(ord($data[$i]), $type, $value);
if ($k >= $datalen)
{
break;
}
$i++;
if ($type == 0) //raw
{
for ($j=0; $j<$pixel_size*$value; $j++)
{
$out .= $data[$j+$i];
$k++;
}
$i += $value*$pixel_size;
}
else //rle
{
for ($j=0; $j<$value; $j++)
{
$out .= $data[$i] . $data[$i+1] . $data[$i+2];
if ($pixel_size == 4) $out .= $data[$i+3];
$k++;
}
$i += $pixel_size;
}
}
return $out;
}
function dec_bits($byte, &$type, &$value)
{
$type = ($byte & 0x80) >> 7;
$value = 1 + ($byte & 0x7F);
}
function getimagesizetga($filename)
{
$f = fopen($filename, 'rb');
$header = fread($f, 18);
$header = @unpack( "cimage_id_len/ccolor_map_type/cimage_type/vcolor_map_origin/vcolor_map_len/" .
"ccolor_map_entry_size/vx_origin/vy_origin/vwidth/vheight/" .
"cpixel_size/cdescriptor", $header);
fclose($f);
$types = array(0,1,2,3,9,10,11,32,33);
if (!in_array($header['image_type'], $types))
{
return array(0, 0, 0, 0, 0);
}
if ($header['pixel_size'] > 32)
{
return array(0, 0, 0, 0, 0);
}
return array($header['width'], $header['height'], 'tga', $header['pixel_size'], $header['image_type']);
}
function imagecreatefromtga($filename)
{
$f = fopen($filename, 'rb');
if (!$f)
{
return false;
}
$header = fread($f, 18);
$header = unpack( "cimage_id_len/ccolor_map_type/cimage_type/vcolor_map_origin/vcolor_map_len/" .
"ccolor_map_entry_size/vx_origin/vy_origin/vwidth/vheight/" .
"cpixel_size/cdescriptor", $header);
switch ($header['image_type'])
{
case 2: echo "Image is not compressedn";//no palette, uncompressed
case 10: //no palette, rle
break;
default: die('Unsupported TGA format');
}
if ($header['pixel_size'] != 24 && $header['pixel_size'] != 32)
{
die('Unsupported TGA color depth');
}
$bytes = $header['pixel_size'] / 8;
if ($header['image_id_len'] > 0)
{
$header['image_id'] = fread($f, $header['image_id_len']);
}
else
{
$header['image_id'] = '';
}
$im = imagecreatetruecolor($header['width'], $header['height']);
$size = $header['width'] * $header['height'] * $bytes;
//-- check whether this is NEW TGA or not
$pos = ftell($f);
fseek($f, -26, SEEK_END);
$newtga = fread($f, 26);
if (substr($newtga, 8, 16) != 'TRUEVISION-XFILE')
{
$newtga = false;
}
fseek($f, 0, SEEK_END);
$datasize = ftell($f) - $pos;
if ($newtga)
{
$datasize -= 26;
}
fseek($f, $pos, SEEK_SET);
//-- end of check
$data = fread($f, $datasize);
if ($header['image_type'] == 10)
{
$data = rle_decode($data, $size, $bytes);
}
if (bit5($header['descriptor']) == 1)
{
$reverse = true;
}
else
{
$reverse = false;
}
$i = 0;
$pixels = str_split($data, $bytes);
//read pixels
if ($reverse)
{
for ($y=0; $y<$header['height']; $y++)
{
for ($x=0; $x<$header['width']; $x++)
{
imagesetpixel($im, $x, $y, dwordize($pixels[$i]));
$i++;
}
}
}
else
{
for ($y=$header['height']-1; $y>=0; $y--)
{
for ($x=0; $x<$header['width']; $x++)
{
imagesetpixel($im, $x, $y, dwordize($pixels[$i]));
$i++;
}
}
}
fclose($f);
return $im;
}
function dwordize($str)
{
$a = ord($str[0]);
$b = ord($str[1]);
$c = ord($str[2]);
return $c*256*256 + $b*256 + $a;
}
function bit5($x)
{
return ($x & 32) >> 5;
}
这是从脚本直接创建的输出PNG图像:
如果你更喜欢直接下载链接而不是粘贴固定代码,我在这里给你完整的PHP文件:https://www.sendspace.com/file/92uir9
在一天结束时,只需更改tga.PHP文件,一切都将自动运行. (编辑:北几岛)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|