converter 24bits RGB para Argb16
-
20-09-2019 - |
Pergunta
Eu tenho que ler um 24bpp Bitmap
e converter cada pixel de RGB24
para ARGB16
.
Eu usei o seguinte código,
#define ARGB16(a, r, g, b) ( ((a) << 15) | (r)|((g)<<5)|((b)<<10))
Mas não estou obtendo a saída necessária.
Qualquer ajuda seria muito apreciada.
Solução
Quebre. Vamos continuar a usar macros:
#define TRUNCATE(x) ((x) >> 3)
#define ARGB16(a,r,g,b) ((a << 15) | (TRUNCATE(r) << 10) | (TRUNCATE(g) << 5) | TRUNCATE(b)))
Isso pressupõe que o alfa é apenas um bit.
Outras dicas
Como os valores RGB provavelmente são 8 bits cada, você ainda precisa truncá -los para cinco bits para que eles não "se sobreponham" no valor do argb16.
A maneira mais fácil de truncá -los é provavelmente o Bitshift para a direita por três lugares.
Parece -me que você provavelmente quer mascarar os pedaços de que não precisa de R, G e B. Talvez algo assim:
#define ARGB16(a, r, g, b) ( ((a) << 15) | (r>>3)|((g>>3)<<5)|((b>>3)<<10))
EDIT: Opa, acho que a resposta de Michael Buddingh provavelmente está certa - você vai querer mudar, isso lhe dá os bits mais significativos.
Eu usaria uma máscara de bit para me livrar dos bits que você não precisa: (ColorValue & 0x1f).
Mude o valor da cor para os 3 bits certos (parece ser a melhor opção).
E é um << 15 realmente o que você precisa? Você confiaria no fato de que o 0 bit é 0 ou 1 para definir ou desativar o bit alfa. Portanto, se o seu valor alfa for 0xfe, o bit alfa seria 0, enquanto se fosse 0x01, seria 1.
Você pode querer escalar em vez de truncat.
Veja o componente R, por exemplo, 0xDE(222)
em 24 bits RGB se tornará 0x1A = (222.0/0xFF)*0x1F
em 16 bits RGB.
Eu tenho o código abaixo:
FILE *inFile;
BmpHeader header;
BmpImageInfo info;
Rgb *palette;
int i = 0;
inFile = fopen( "red.bmp", "rb" );
fread(&header, 1, sizeof(BmpHeader), inFile);
fread(&info, 1, sizeof(BmpImageInfo), inFile);
palette = (Rgb*)malloc(sizeof(Rgb) * info.numColors);
fread(palette, sizeof(Rgb), info.numColors, inFile);
unsigned char buffer[info.width*info.height];
FILE *outFile = fopen( "red.a", "wb" );
Rgb *pixel = (Rgb*) malloc( sizeof(Rgb) );
int read, j;
for( j=info.height; j>0; j-- )
{
for( i=0; i<info.width; i++ )
{
fread(pixel, 1, sizeof(Rgb), inFile);
buffer[i] = ARGB16(0, pixel->red, pixel->green, pixel->blue);
}
}
fwrite(buffer, 1, sizeof(buffer), outFile);
E estou lendo uma imagem vermelha (255 0 0) e estou usando a função definida por você acima (#Define argb16 (a, r, g, b) (((a) << 15) | (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10))), mas o arquivo de saída mostra -me: 1f 1f 1f quando estou abrindo o arquivo com um hexaeditor em vez de 7c00 ..