ARGB8888 and ARGB1555 format conversion


Preface

Recently, I have been studying image color formats and need to use image color format conversion, which is recorded here.


1. RGB color space

  • The RGB color space is based on the three basic colors of R (Red: red), G (Green: green), and B (Blue: blue), which are superimposed to varying degrees to produce rich and colorful colors, commonly known as the three-primary color mode.
  • Scientists have discovered that the three colors red, green and blue can be synthesized in different proportions and evolve into any other color.

2. Common formats

  • RGB888: Indicates that R, G, and B are represented by 8 bits (1Byte) respectively, with a total of 24 bits (3Bytes), also called 24 bits wide.
  • RGB565: Indicates that R is represented by 5 bits, G is represented by 6 bits, and B is represented by 5 bits, a total of 16 bits (2Bytes), 16 bits wide.
  • ARGB1555: Indicates that A (whether it is transparent or not) is represented by 1 bit, and RGB is represented by 5 bits respectively.

3. Format conversion

From large to small
For example: RGB888 to RGB565
requires quantization and compression to compress 8-bit data into 5-bit and 6-bit; compression rule: take the high bit, for example: 8-bit to 5-bit, take the high 5-bit, and then convert the obtained RGB data , arranged in the order of RGB565.
Quantization is compressed, but accuracy is lost .

From small to large
For example: RGB565 to RGB888
requires quantization compensation; compensation rules: fill the original data to the high bit, and use the low bit of the original data to compensate for the low bit, if there are still unfilled bits, continue to use the low bit of the original data to cycle compensate.

4. ARGB8888 and ARGB8888 mutual conversion

#include <stdio.h>
#include <stdint.h>


unsigned int Rgb888toArgb8888(unsigned int rgb24, int a)
{
    
    
	if(a <= 0)
		return 0;
	return (a << 24) + rgb24;
}

unsigned int argb1555_to_argbB8888(unsigned short c)
{
    
    
    const unsigned int a = c&0x8000, r = c&0x7C00, g = c&0x03E0, b = c&0x1F;
    const unsigned int rgb = (r << 9) | (g << 6) | (b << 3);
    return (a*0x1FE00) | rgb | ((rgb >> 5) & 0x070707);
}

unsigned short argb8888_to_argb1555(unsigned int color)
{
    
    
	unsigned int a = (((color&0xff000000)>>24) +127)/255;
	unsigned int r = (((color&0x00ff0000)>>16)*31 +127)/255;
	unsigned int g = (((color&0x0000ff00)>>8)*31 +127)/255;
	unsigned int b = (((color&0x000000ff))*31 +127)/255;

	unsigned short argb1555 = (a << 15) | (r <<  10) | (g << 5) | b;

	return argb1555;
}

int main(int argc, char *argv[])
{
    
    
	unsigned int rgb32 = Rgb888toArgb8888(0x92d050, 0xff);
	printf("rgb32:%x\n", rgb32);
	unsigned short argb1555 = argb8888_to_argb1555(rgb32);
	printf("argb1555:%x\n", argb1555);
	unsigned int color = argb1555_to_argbB8888(argb1555);
	printf("argb8888:%x\n", color);
    return 0;
}

5. Summary

What you need to know is that converting from large to small will lose precision. After color compression, it will be different from the original color! The color I tried here will be lighter than the original color.

Guess you like

Origin blog.csdn.net/weixin_37926485/article/details/127862610