libwebp-compress/convert_image_to_webp.cpp
2024-11-06 11:40:07 +08:00

64 lines
2.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 数据
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 width, height, channels;
// 使用 stb_image 解码输入图像(强制加载为 RGB 而非 RGBA
unsigned char *decoded_data = stbi_load_from_memory(input_data, input_size, &width, &height, &channels, 3); // 强制加载为 RGB
if (!decoded_data) {
return nullptr; // 图像解码失败
}
// 如果需要调整尺寸,则进行调整
unsigned char *resized_data = decoded_data;
if (target_width > 0 && target_height > 0) {
// 分配用于存储调整大小后图像的缓冲区
resized_data = (unsigned char *)malloc(target_width * target_height * 3); // RGB 3 通道
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,
resized_data, target_width, target_height, 0, 3);
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;
*output_size = WebPEncodeRGB(resized_data, target_width, target_height, target_width * 3, quality_factor, &webp_output);
// 释放解码后的图像内存
stbi_image_free(decoded_data);
if (resized_data != decoded_data) {
free(resized_data); // 如果调整了大小,则释放调整大小后的数据
}
return webp_output; // 返回 WebP 编码后的数据
}
}