JS checks whether the png image has an alpha channel

1. Demand background

When the company was making the developer platform, it took into account that App applications need to have certain requirements for icons when they are put on the Apple Developer Market, which includes not being able to carry the Alpha channel.

2. Alpha channel description

It should be noted that the alpha channel does not simply refer to transparency, and an opaque image can also carry an alpha channel. If you just want to judge whether it contains transparency, please refer to: JS detects whether a PNG image has a transparent background, header image, etc. To verify Alpha, we first need to obtain the detailed information of the image. Here I read the binary of the image data for details.

By reading the story of AlloyTeam's png , I have some understanding of image binary data, and draw the following conclusions:

        The bits [0, 8] represent the type of the png image, which can be used to judge the image type, and the value is: [137, 80, 78, 71, 13, 10, 26, 10];

        [8, 12] bits indicate the length of the data content;

        [12, 16] bits indicate the data block type;

When the data of [12, 16] is converted into bytecode as IHDR, it means that the picture has data such as width, height and depth:

        [16, 20] 16~19 bits represent the width of the picture

        [20~24] bits represent the height of the picture

        [24] bits represent the depth of the picture

        [25] bits indicate the color type of the picture

[25] is the data we need, it has 5 values:

color type Number of occupied channels describe
0 1 Grayscale image, only 1 gray channel
2 3 rgb true color image, with RGB3 channels
3 1 Indexed color image, only one channel of index value
4 2 grayscale image + alpha channel
6 4 rgba4 channels

3. Implementation steps

  1. Read image buffer data
  2. Convert buffer data into binary data
  3. Determine the data block type
  4. Determine whether to include the Alpha channel according to the value in [25]

4. Code Sharing

const readBuffer = (file: any) => {
	return new Promise((resolve, reject) => {
		const reader = new FileReader();
		reader.onload = () => {
			resolve(reader.result);
		};
		reader.onerror = reject;
		reader.readAsArrayBuffer(file);
	});
};

export const isHasAlpha = async (file: any) => {
    // 读取图片缓存区数据
	const buffers = await readBuffer(file);
    // 缓存区数据转成二进制数据,并获取0~25位数据
	const uint8Array = new Uint8Array(buffers, 0, 26);
    // 获取类型
	let type = ''
	uint8Array.slice(12, 16).forEach((number) => {
		type += String.fromCharCode(number)
	})
    // 判断类型和[25]的数值
	if (type == 'IHDR' && (uint8Array[25] == 6 || uint8Array[25] == 4 || uint8Array[25] == 3)) {
		return true
	} else {
		return false
	}
}

5. Reference text

png story

JS judges whether PNG contains alpha channel

Guess you like

Origin blog.csdn.net/m0_68349563/article/details/129381796