我可以使用 stb_image_write.h 将 JPG 图像写入内存吗?

Can i write a JPG image to memory with stb_image_write.h?

本文关键字:图像 内存 JPG 可以使 stb image 我可以 write      更新时间:2023-10-16

我想从stbir_resize_uint8(从 https://github.com/nothings/stb/blob/master/stb_image_resize.h(中获取结果,将其压缩为JPG并将其存储到缓冲区而不将其保存到磁盘。

我已经将stbir_resize_uint8的结果作为unsigned char*,但我不知道如何以 JPG 的形式获取指向数据的指针。这可以用 stb_image_write.h 完成还是我需要另一个库?

我尝试使用这样的 https://github.com/nothings/stb/blob/master/stb_image_write.hstbi_write_jpg_to_func

//图片.h

static unsigned char memoryJPG[32768];
static int thumbSize = 0;
struct ImageInfo
{
unsigned char* data;
int size;
};
class Image 
{
public:
unsigned char* writeToMemoryAsJPG(const int quality = 90);
private:
unsigned char* mImageData = nullptr;
int mWidth;
int mHeight;
int mDepth;
};

图片.cpp

ImageInfo Image::writeToMemoryAsJPG(const int quality)
{
auto rv = stbi_write_jpg_to_func([](void *context, void *data, int size)
{
if (size > 32768) size = 32768;
memcpy(memoryJPG, data, size);
thumbSize = size;
}, nullptr, mWidth, mHeight, mDepth, mImageData, quality);
ImageInfo ii;
ii.data = memoryJPG;
ii.size = thumbSize;
return ii;
}

这不会返回任何内容,但即使它确实返回了正确的结果,静态变量也非常丑陋。 如何在没有任何静态变量的情况下编写此方法?

这是我所做的,但这不是一个好的解决方案,因为如果启用了编译器优化,这可能会有内存对齐问题,所以如果有人有更好的解决方案,请发布答案。

事实证明,我以错误的方式使用了stbi_write_jpg_to_func。显然,该函数是按顺序调用的,每次调用它时都会从 JPG 中检索一段可变长度的数据。因此,每次调用该函数时,我只需将该数据添加到内存缓冲区中即可。像这样:

图片.h

struct ImageData
{
unsigned char data[32768];
size_t size = 0;
};
class Image 
{
public:
unsigned char* writeToMemoryAsJPG(const int quality = 90);
private:
unsigned char* mImageData = nullptr;
int mWidth;
int mHeight;
int mDepth;
};

图片.cpp

ImageData Image::writeToMemoryAsJPG(const int quality)
{
ImageData ii;
auto rv2 = stbi_write_jpg_to_func(
[](void *context, void *data, int size)
{
memcpy(((ImageData*)context)->data + ((ImageData*)context)->size, data, size);
((ImageData*)context)->size += size;
}
,&ii, mWidth, mHeight, mDepth, mImageData, quality);
return ii;
}

我在 stbi 项目的 github 页面问题中找到了一个通用解决方案

typedef struct {
int last_pos;
void *context;
} custom_stbi_mem_context;
// custom write function
static void custom_stbi_write_mem(void *context, void *data, int size) {
custom_stbi_mem_context *c = (custom_stbi_mem_context*)context; 
char *dst = (char *)c->context;
char *src = (char *)data;
int cur_pos = c->last_pos;
for (int i = 0; i < size; i++) {
dst[cur_pos++] = src[i];
}
c->last_pos = cur_pos;
}
// get image, width, height and channels
// how to use it:
custom_stbi_mem_context context;
context.last_pos = 0;
context.context = (void *)buffer;
int result = stbi_write_jpg_to_func(custom_stbi_write_mem, &context, width, height, channels, image, WS_JPEG_COMPRESSION);

如果问题被接受,则可以在标头中添加函数stbi_write_jpg_to_mem,请查看:

https://github.com/nothings/stb/issues/1132

我希望这可以有用!