ImageMagick颜色深度转换

ImageMagick颜色深度转换,imagemagick,imagemagick-convert,Imagemagick,Imagemagick Convert,我有数千个tga文件(没有调色板),其中包含RGBA4444数据(我知道通常tga文件不包含RGBA4444数据)。我想把它们转换成RGBA8888数据。我使用以下命令行: convert -depth 4 woody4.tga -depth 8 woody8.tga 在这种情况下,woody4.tga是原始的RGBA4444文件,而woody8.tga是目标的RGBA8888文件,但它不会改变我图片的颜色,我缺少什么 谢谢 皮埃尔 编辑: 非常感谢马克,我已经成功地用你的程序转换了10000

我有数千个
tga
文件(没有调色板),其中包含
RGBA4444
数据(我知道通常
tga
文件不包含
RGBA4444
数据)。我想把它们转换成RGBA8888数据。我使用以下命令行:

convert -depth 4 woody4.tga -depth 8 woody8.tga
在这种情况下,
woody4.tga
是原始的
RGBA4444
文件,而
woody8.tga
是目标的
RGBA8888
文件,但它不会改变我图片的颜色,我缺少什么

谢谢

皮埃尔

编辑:

非常感谢马克,我已经成功地用你的程序转换了10000多个TGA,结果非常好,与原来的TGA是正确的!如果没有并行命令,这是不可能的!最后一点,我有大约50 TGA大(游戏背景),用RGBA5650编码,而不是RGBA4444,我如何修改您的程序来管理RGBA5650?非常感谢

更新答案。 大约过了一会儿。我修改并简化了一个C程序以进行转换

//tga2img.c
#包括
#包括
#包括
类型定义结构{
无符号字符idlength;
无符号字符颜色映射类型;
无符号字符数据类型码;
短整型彩色地图;
短整数长度;
无符号字符颜色映射深度;
短整数x_原点;
短内y_起源;
短整数宽度;
短内高度;
无符号字符比特像素;
无符号字符图像描述符;
}收割台;
类型定义结构{
int扩展偏移;
int developeroffset;
字符签名[16];
无符号字符p;
无符号字符n;
}页脚;
int main(int argc,const char*argv[]{
收割台tga_收割台;
页脚tga_页脚;
文件
*fd;
尺寸
tga_数据_尺寸,
tga_像素_尺寸,
我
J
无符号字符
*tga_数据,
*缓冲器;
常量字符
*输入,
*产出;
如果(argc!=3){
printf(“用法:\n\t%s\n”,argv[0]);
返回1;
}
输入=argv[1];
输出=argv[2];
fd=fopen(输入,“rb”);
如果(fd==NULL){
fprintf(stderr,“无法读取TGA输入\n”);
返回1;
}
/********\
*塔尔加*
\*********/
#布拉格马克塔加
//读取TGA标题
fread(&tga_header.idlength,sizeof(unsigned char),1,fd);
fread(&tga_header.colormaptype,sizeof(unsigned char),1,fd);
fread(&tga_header.datatypecode,sizeof(unsigned char),1,fd);
fread(&tga_header.colorMapOrigin,sizeof(短int),1,fd);
fread(和tga_标题,长度、尺寸(短整型),1,fd);
fread(&tga_header.colorMapDepth,sizeof(无符号字符),1,fd);
fread(&tga_头.x_原点,sizeof(短整数),1,fd);
fread(&tga_头.y_原点,sizeof(短整数),1,fd);
fread(&tga_页眉宽度、尺寸(短整型)、1、fd);
fread(和tga_收割台高度、尺寸(短整型)、1、fd);
fread(&tga_header.bitsperpixel,sizeof(unsigned char),1,fd);
fread(&tga_header.imagedescriptor,sizeof(unsigned char),1,fd);
//计算尺寸
tga_pixel_size=tga_header.bitsperpixel/8;
tga_数据_大小=tga_标题。宽度*tga_标题。高度*tga_像素_大小;
//读取图像数据
tga_数据=malloc(tga_数据大小);
fread(tga_数据,1,tga_数据大小,fd);
//阅读TGA页脚。
fseek(fd,-26,SEEK_END);
fread(&tga_footer.extensionoffset,sizeof(int),1,fd);
fread(&tga_footer.developeroffset,sizeof(int),1,fd);
fread(&tga_footer.signature,sizeof(char),16,fd);
fread(&tga_footer.p,sizeof(unsigned char),1,fd);
fread(&tga_footer.n,sizeof(unsigned char),1,fd);
fclose(fd);
缓冲区=malloc(tga_收割台宽度*tga_收割台高度*4);
#pragma标记RGBA4444至RGBA888
对于(i=0,j=0;iimageTypeCode!=2&&tgaFile->imageTypeCode!=3)
{
fclose(文件管理器);
返回false;
}
//读取13字节我们不需要的数据。
fread(&sintBad,sizeof(short int),1,filePtr);
fread(&sintBad,sizeof(short int),1,filePtr);
fread(&ucharBad,sizeof(unsigned char),1,filePtr);
fread(&sintBad,sizeof(short int),1,filePtr);
fread(&sintBad,sizeof(short int),1,filePtr);
//读取图像的宽度和高度。
fread(&tgaFile->imageWidth,sizeof(short int),1,filePtr);
fread(&tgaFile->imageHeight,sizeof(short int),1,filePtr);
//读取位深度。
fread(&tgaFile->位计数,sizeof(unsigned char),1,filePtr);
//读取一字节我们不需要的数据。
fread(&ucharBad,sizeof(unsigned char),1,filePtr);
//颜色模式->3=BGR,4=BGRA。
colorMode=tgaFile->bitCount/8;
imageSize=tgaFile->imageWidth*tgaFile->imageHeight*colorMode;
//为图像数据分配内存。
tgaFile->imageData=(无符号字符*)malloc(sizeof(无符号字符)*imageSize);
//读取图像数据。
fread(tgaFile->imageData,sizeof(unsigned char),imageSize,filePtr);
//从BGR更改为RGB,以便OpenGL可以读取图像数据。
对于(int-imageIdx=0;imageIdximageData[imageIdx];
tgaFile->imageData[imageIdx]=tgaFile->imageData[imageIdx+2];
tgaFile->imageData[imageIdx+2]=颜色交换;
}
fclose(文件管理器);
返回true;
}

可能需要切换颜色通道的顺序。

更新答案。 经过大约一段时间,我修改并简化了一个C程序来转换

//tga2img.c
#包括
#包括
#包括
类型定义st
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(int argc,char* argv[]){

    unsigned char buf[64];

    FILE* fp=fopen(argv[1],"rb");    
    if(fp==NULL){
       fprintf(stderr,"ERROR: Unable to open %s\n",argv[1]);
       exit(1);
    }

    // Read TGA header of 18 bytes, extract width and height
    fread(buf,1,18,fp);  // 12 bytes junk, 2 bytes width, 2 bytes height, 2 bytes junk
    unsigned short w=buf[12]|(buf[13]<<8);
    unsigned short h=buf[14]|(buf[15]<<8);

    // Write PAM header
    fprintf(stdout,"P7\n");
    fprintf(stdout,"WIDTH %d\n",w);
    fprintf(stdout,"HEIGHT %d\n",h);
    fprintf(stdout,"DEPTH 4\n");
    fprintf(stdout,"MAXVAL 255\n");
    fprintf(stdout,"TUPLTYPE RGB_ALPHA\n");
    fprintf(stdout,"ENDHDR\n");

    // Read 2 bytes at a time RGBA4444
    while(fread(buf,2,1,fp)==1){
       unsigned char out[4];
       out[0]=(buf[1]&0x0f)<<4;
       out[1]=buf[0]&0xf0;
       out[2]=(buf[0]&0x0f)<<4;
       out[3]=buf[1]&0xf0;
       // Write the 4 modified bytes out RGBA8888
       fwrite(out,4,1,stdout);
    }
    fclose(fp);
    return 0;
}
gcc targa.c -o targa
clang targa.c -o targa
./targa someImage.tga > someImage.pam
convert someImage.pam someImage.png
./targa illu_evolution_01.tga | convert - result.png
./targa illu_evolution_01.tga | convert - result.bmp
parallel --eta './targa {} | convert - {.}.png' ::: *.tga
find . -name \*tga -print0 | parallel -0 --eta './targa {} | convert - {.}.png'
brew install parallel
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(int argc,char* argv[]){

    unsigned char buf[64];

    FILE* fp=fopen(argv[1],"rb");    
    if(fp==NULL){
       fprintf(stderr,"ERROR: Unable to open %s\n",argv[1]);
       exit(1);
    }

    // Read TGA header of 18 bytes, extract width and height
    fread(buf,1,18,fp);  // 12 bytes junk, 2 bytes width, 2 bytes height, 2 bytes junk
    unsigned short w=buf[12]|(buf[13]<<8);
    unsigned short h=buf[14]|(buf[15]<<8);

    // Write PPM header
    fprintf(stdout,"P6\n");
    fprintf(stdout,"%d %d\n",w,h);
    fprintf(stdout,"255\n");

    // Read 2 bytes at a time RGBA5650
    while(fread(buf,2,1,fp)==1){
       unsigned char out[3];
       out[0]=buf[1]&0xf8;
       out[1]=((buf[1]&7)<<5) | ((buf[0]>>3)&0x1c);
       out[2]=(buf[0]&0x1f)<<3;
       // Write the 3 modified bytes out RGB888
       fwrite(out,3,1,stdout);
    }
    fclose(fp);
    return 0;
}
convert illu_evolution_01.tga -depth 16 -channel R -fx "(((r*255)<<10) | ((g*255)<<5) | (b*255) | ((a*255)<<15))/255" \
   \( -clone 0 -channel R -fx "((((r*255)>>12)&15)<<4)/255"     \) \
   \( -clone 0 -channel R -fx "((((r*255)>>8 )&15)<<4)/255"     \) \
   \( -clone 0 -channel R -fx "((((r*255)    )&15)<<4)/255"     \) \
   -delete 0 -set colorspace RGB -combine -colorspace sRGB result.png

# The rest is just debug so you can see the reconstructed channels in [rgba].png
convert result.png -channel R -separate r.png
convert result.png -channel G -separate g.png
convert result.png -channel B -separate b.png
convert result.png -channel A -separate a.png
A R R R R R G G G G G B B B B B           <--- what IM saw
R R R R G G G G B B B B A A A A           <--- what it really meant