- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在 this code 工作并考虑到为 32 位“修复”它的注释,但它似乎仍然不起作用。我很确定它与 TGA descriptor 有关.这将使用 0-3 位作为 alpha channel 深度,对于 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()
知道像素格式大小的函数,所以 int for
当我们调用它时循环我们需要传递这个参数,所以我们还需要更改以下行:
行141
: $data = rle_decode($data, $size, $bytes);
因此函数原型(prototype)变为:
行9
: function rle_decode($data, $datalen, $pixel_size)
现在你可以看到这个函数有多个3
魔数(Magic Number)(即:for ($j = 0; $j<3*$value; $j++)
第 29 行)。所有这些都必须替换为像素大小参数。 (3 代表 24 bits
和 4 代表 32 bits
)
此外,有时在创建像素时它只会写入 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 compressed\n";//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
文件,一切都会自动运行。
关于php - 将 32 位 TGA 转换为 PNG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24709142/
我正在制作一款游戏。我想隐藏我所有的 .tga 文件。我将所有文件的字符串内容连接在一个文件中,以使其对玩家不可见。我希望我的程序通过创建临时 .tga 文件来加载图片保存的内容。 因此,我正在尝试从
我正在寻找用于 java 的小型免费 TGA 图像加载类或库。理想情况下,结果是 BufferedImage。 是的,我已经用谷歌搜索过,但大多数结果都已过时,或者是相当大的库,其中包含许多我不需要的
当从内存写入图像缓冲区(包含从 tga 文件加载的 RGBA 像素数据)到文件返回时,我有时观察到一个奇怪的行为 图像缓冲区是从 TGA 文件加载的,该文件使用从该线程窃取和改编的算法: Loadin
我正在编写一个 .tga 阅读器。我可以完美地读取标题,然后我想读取文件的数据部分,但是如果我到达那里,它会给我错误: Unhandled exception at 0x76ffa2ce in TGA
我一直在学习有关加载 TGA 文件的基本 OpenGl 教程,以用作 3d 对象的纹理。我已经能够从 TGA header 加载数据,但是当我尝试加载实际图像数据时,它失败了。我不确定哪里出了问题。这
查看LibGDX BitmapFont documentation我没有看到有办法将多个 .tga 文件添加到 BitmapFont 中。当字体大小大于 ~42 时,这只会给我带来麻烦,因此它必须创建
我的 Targa 阅读器有非常非常小的问题。一个像素关闭,另外 2 个像素为黑色 :S 我正在加载的 24 位 targa 文件如下所示: 请注意左上角的白色像素。左上角的第一个像素是白色的。 但是当
我正在尝试读取我在 Paint.net 中创建的文件的 TGA header 。好像哪里不对劲。如果我使用规范中的 header 结构,如下所示: typedef struct { CHAR
我写了一个 TGA 加载器来加载 TGA 文件。它可以很好地加载和保存 32 位 TGA 文件,但在加载和保存 24 位时,它就搞砸了。 来自 Photoshop 的 TGA 24 位文件示例: 我的
我想就 .tga 文件格式解析问题获得一些帮助。我有我使用了很长时间的代码: int fileLength = Input.tellg(); vecto
我正在将 OpenGL FBO 内容写入 TGA 文件。我以 BGR 格式读取像素并保存到未压缩的 TGA。奇怪的是,如果我保存单调颜色(无纹理),我的导出器写入正常,但如果像素数据出现从纹理中我得到
我目前正在尝试使用 C++ 加载标记文件并使用 OpenGL 渲染它。目前颜色都混合了(红色变成蓝色,绿色变成红色,蓝色变成绿色)。我目前将其放入显存的代码是。 glTexImage2D(GL_TEX
在我的应用程序中,我使用的是图像,这些图像也可以是 .tga(Targa Graphic) 文件,当我使用 .tga 文件创建 BitmapImage 的实例时,它抛出异常说“没有适合完成此操作的成像
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 3 年前。 Improve th
给我一个图像加载库,它可以加载 JPG、PNG、TIFF、TGA 等格式。如果它能告诉我像素格式,如 R8G8B8、R5G6B5 等,那就太好了。 最佳答案 BufferedImage 是一种非常
我在 this code 工作并考虑到为 32 位“修复”它的注释,但它似乎仍然不起作用。我很确定它与 TGA descriptor 有关.这将使用 0-3 位作为 alpha channel 深度,
TGA 图像规范包含以下两个字段: Field 5.1 (2 bytes) - X-origin of Image: These bytes specify the absolute hori
我正在尝试为我的 3D 模型创建纹理。只要我只加载图像文件,它就可以正常工作。我正在使用 Microsoft Visual C++ 2008 Express,我一直在寻找解决这个“问题”的方法,将资源
我有一个 TGA 文件和一个库,里面已经有了我阅读和使用 TGA 所需的一切。 这个类有一个叫做pixels()的方法,它返回一个指针指向存储像素为RGBRGBRGB的内存区域... 我的问题是,如何
我正在尝试加载一个 tga/bmp 文件。这工作正常,但最终结果如下所示: 我尝试加载的图像如下所示: 我正在使用的一些代码: GLuint texture; const char* filename
我是一名优秀的程序员,十分优秀!