libwebp-compress/convert_image_to_webp.cpp

67 lines
2.9 KiB
C++
Raw Normal View History

2024-11-06 03:40:07 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "webp/encode.h" // WebP 头文件,用于编码 WebP
#include "stb_image.h" // stb_image 头文件,用于解码 PNG/JPG
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "stb_image_resize.h"
extern "C" {
// 将输入的 JPG/PNG 数据转换为 WebP并返回 WebP 数据
2024-12-20 07:41:32 +00:00
unsigned char *convert_image_to_webp(const uint8_t *input_data, size_t input_size, int target_width, int target_height, float quality_factor, size_t *output_size, int preserve_alpha = 0) {
2024-11-06 03:40:07 +00:00
int width, height, channels;
2024-12-20 07:41:32 +00:00
// 使用 stb_image 解码输入图像(根据 preserve_alpha 决定加载通道数)
unsigned char *decoded_data = stbi_load_from_memory(input_data, input_size, &width, &height, &channels, preserve_alpha ? 4 : 3); // 根据是否保留 alpha 通道加载
2024-11-06 03:40:07 +00:00
if (!decoded_data) {
return nullptr; // 图像解码失败
}
// 如果需要调整尺寸,则进行调整
unsigned char *resized_data = decoded_data;
if (target_width > 0 && target_height > 0) {
// 分配用于存储调整大小后图像的缓冲区
2024-12-20 07:41:32 +00:00
resized_data = (unsigned char *)malloc(target_width * target_height * (preserve_alpha ? 4 : 3)); // 根据是否保留 alpha 通道调整缓冲区大小
2024-11-06 03:40:07 +00:00
if (!resized_data) {
// 内存分配失败的处理
fprintf(stderr, "Failed to allocate memory for resized image.\n");
stbi_image_free(decoded_data); // 释放原始解码数据
return NULL;
}
// 使用 stb_image_resize 调整图像大小
int result = stbir_resize_uint8(decoded_data, width, height, 0,
2024-12-20 07:41:32 +00:00
resized_data, target_width, target_height, 0, preserve_alpha ? 4 : 3);
2024-11-06 03:40:07 +00:00
if (!result) {
// 如果调整大小失败,释放已分配的内存
fprintf(stderr, "Image resizing failed.\n");
free(resized_data);
stbi_image_free(decoded_data);
return NULL;
}
} else {
target_width = width;
target_height = height;
}
// 使用 libwebp 的有损编码函数WebPEncodeRGB将 RGB 图像编码为 WebP
unsigned char *webp_output = NULL;
2024-12-20 07:41:32 +00:00
if (preserve_alpha) {
*output_size = WebPEncodeRGBA(resized_data, target_width, target_height, target_width * 4, quality_factor, &webp_output);
} else {
*output_size = WebPEncodeRGB(resized_data, target_width, target_height, target_width * 3, quality_factor, &webp_output);
}
2024-11-06 03:40:07 +00:00
// 释放解码后的图像内存
stbi_image_free(decoded_data);
if (resized_data != decoded_data) {
free(resized_data); // 如果调整了大小,则释放调整大小后的数据
}
return webp_output; // 返回 WebP 编码后的数据
}
}