直接从releases下载列表里下载即可,里面有头文件和静态库,可以直接拿来使用。Windows版本的最近以来的都是64位的了,支持32位的较新的版本是:libwebp-1.0.3-windows-x86
。
如果是自己在Windows上编译,可以参考「Makefile、CMake、CMakeLists.txt、GCC、Clang、LLVM、MinGW、交叉编译」,及 编译 WebP - Google for Developers,在Windows搜索栏里搜索prompt
找到VisualStudio
的对应版本的控制台,进入到源码目录下,直接调用nmake
命令即可编译,非常简单:
nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
对于老版本的源码编译后的 libwebp.lib
里面的不会包含解密和保存文件的相关函数,需要重新修改下编译脚本。找到 Makefile.vc 中的:
LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
$(UTILS_ENC_OBJS) $(DLL_OBJS) $(IMAGEIO_DEC_OBJS)
增加:$(IMAGEIO_ENC_OBJS) $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
,修改为:
LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
$(UTILS_ENC_OBJS) $(DLL_OBJS) $(IMAGEIO_ENC_OBJS) $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
例如想封装一个WebP图片转其他格式图片的函数,可以参考 libwebp
源码中的 examples/dwebp.c 文件。封装如下。
头文件 dwebp.h
:
// dwebp.h
#pragma once
// 判断是否是webp图片
bool IsWebpImage(const char* filename);
// webp图片转换为png图片
bool Webp2Image(const char* in_file, const char* out_file, const char* pixel_format = nullptr);
对应的 dwebp.cpp
:
// dwebp.cpp
#define HAVE_WINCODEC_H
#include "dwebp.h"
#include "./decode.h"
#include "./imageio/image_enc.h"
#include "./imageio/webpdec.h"
#include <locale>
#include <codecvt>
#include <string>
#include <iostream>
#include <fstream>
// 判断是否是webp图片
// 参考:https://cpp.hotexamples.com/zh/examples/-/-/WebPGetInfo/cpp-webpgetinfo-function-examples.html ImageFromData
bool IsWebpImage(const char* filename) {
bool yes = false;
std::ifstream in_file(filename, std::ios::binary);
in_file.seekg(0, std::ios::end);
int file_size = (int)in_file.tellg();
if (file_size > 0) {
uint8_t* buff = new uint8_t[file_size];
if (buff) {
in_file.seekg(0);
in_file.read((char*)buff, file_size);
int w = 0, h = 0;
yes = WebPGetInfo((const uint8_t*)buff, file_size, &w, &h);
delete[] buff;
}
}
return yes;
}
// webp图片转换为图片
// 参考libwebp源码:examples/dwebp.c https://github.com/webmproject/libwebp/blob/1.0.3/examples/dwebp.c
#pragma comment(lib,"libwebp.lib")
#pragma comment(lib,"libwebpdemux.lib")
bool Webp2Image(const char* in_file, const char* out_file, const char* pixel_format/* = nullptr*/) {
bool success = false;
WebPDecoderConfig config;
WebPDecBuffer* const output_buffer = &config.output;
WebPBitstreamFeatures* const bitstream = &config.input;
WebPOutputFileFormat format = PNG;
const uint8_t* data = NULL;
int incremental = 0;
VP8StatusCode status = VP8_STATUS_OK;
size_t data_size = 0;
if (!WebPInitDecoderConfig(&config)) {
return success;
}
if (pixel_format) {
const char* const fmt = pixel_format;
if (!strcmp(fmt, "RGB")) format = RGB;
else if (!strcmp(fmt, "RGBA")) format = RGBA;
else if (!strcmp(fmt, "BGR")) format = BGR;
else if (!strcmp(fmt, "BGRA")) format = BGRA;
else if (!strcmp(fmt, "ARGB")) format = ARGB;
else if (!strcmp(fmt, "RGBA_4444")) format = RGBA_4444;
else if (!strcmp(fmt, "RGB_565")) format = RGB_565;
else if (!strcmp(fmt, "rgbA")) format = rgbA;
else if (!strcmp(fmt, "bgrA")) format = bgrA;
else if (!strcmp(fmt, "Argb")) format = Argb;
else if (!strcmp(fmt, "rgbA_4444")) format = rgbA_4444;
else if (!strcmp(fmt, "YUV")) format = YUV;
else if (!strcmp(fmt, "YUVA")) format = YUVA;
}
if (!LoadWebP(in_file, &data, &data_size, bitstream)) {
goto Exit;
}
switch (format) {
case PNG:
#ifdef HAVE_WINCODEC_H
output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
#else
output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB;
#endif
break;
case PAM:
output_buffer->colorspace = MODE_RGBA;
break;
case PPM:
output_buffer->colorspace = MODE_RGB; // drops alpha for PPM
break;
case BMP:
output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
break;
case TIFF:
output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB;
break;
case PGM:
case RAW_YUV:
output_buffer->colorspace = bitstream->has_alpha ? MODE_YUVA : MODE_YUV;
break;
case ALPHA_PLANE_ONLY:
output_buffer->colorspace = MODE_YUVA;
break;
// forced modes:
case RGB: output_buffer->colorspace = MODE_RGB; break;
case RGBA: output_buffer->colorspace = MODE_RGBA; break;
case BGR: output_buffer->colorspace = MODE_BGR; break;
case BGRA: output_buffer->colorspace = MODE_BGRA; break;
case ARGB: output_buffer->colorspace = MODE_ARGB; break;
case RGBA_4444: output_buffer->colorspace = MODE_RGBA_4444; break;
case RGB_565: output_buffer->colorspace = MODE_RGB_565; break;
case rgbA: output_buffer->colorspace = MODE_rgbA; break;
case bgrA: output_buffer->colorspace = MODE_bgrA; break;
case Argb: output_buffer->colorspace = MODE_Argb; break;
case rgbA_4444: output_buffer->colorspace = MODE_rgbA_4444; break;
case YUV: output_buffer->colorspace = MODE_YUV; break;
case YUVA: output_buffer->colorspace = MODE_YUVA; break;
default: goto Exit;
}
if (incremental) {
status = DecodeWebPIncremental(data, data_size, &config);
} else {
status = DecodeWebP(data, data_size, &config);
}
if (status != VP8_STATUS_OK) {
PrintWebPError(in_file, status);
goto Exit;
}
if (out_file != NULL) {
success = WebPSaveImage(output_buffer, format, out_file);
}
Exit:
WebPFreeDecBuffer(output_buffer);
WebPFree((void*)data);
return success;
}
文档信息
- 本文作者:zhupite
- 本文链接:https://zhupite.com/program/webp.html
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)