[视频编码] Image Stride

在内存中存储一张图片时,并不是按照宽和高的大小尺寸分配比例,然后分配相应大小的内存,通常会在图片的每一行(此处假设图片的扫描方式是光栅扫描)都会有一些填充的字节,这些字节是用来帮助在内存中更好地存储和显示。

而image stride这个概念正是描述真正每一行的像素的个数。具体的定义是:从一行的某一个像素,知道下一行相同的横坐标位置的像素,两者之间相差的像素个数值。通常image stride 是比image width 数值要更大的。
这里写图片描述

从图中我们可以看出,左边是image的width,右边阴影部分就是填充部分(padding)。

内存中的图像有两种存储方式,一种是顺序存储,一种是倒序存储,但是针对两种不同的存储方式,padding部分却都是在“右边”的。
这里写图片描述

据此,我们可以发现,对于顺序的图像,在真实图片中,padding是在右边的,但是在倒序的真实图像中,padding部分是在左边了,那也就是是倒序的图像的padding部分的坐标将会是负数。

JPEG(Joint Photographic Experts Group)是一种非常常见的图像压缩格式。在C++中,可以使用开源的jpeglib库来进行JPEG图像的编码和解码。下面是一个简单的示例代码: ``` #include <stdio.h> #include <jpeglib.h> void encode_jpeg(const char* filename, unsigned char* image_buffer, int width, int height, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE* outfile; JSAMPROW row_pointer[1]; int row_stride; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); if ((outfile = fopen(filename, "wb")) == NULL) { fprintf(stderr, "Can't open %s\n", filename); exit(1); } jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); jpeg_start_compress(&cinfo, TRUE); row_stride = width * 3; while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); fclose(outfile); jpeg_destroy_compress(&cinfo); } unsigned char* decode_jpeg(const char* filename, int* width, int* height) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; FILE* infile; unsigned char* buffer; JSAMPARRAY buffer_array; int row_stride; if ((infile = fopen(filename, "rb")) == NULL) { fprintf(stderr, "Can't open %s\n", filename); exit(1); } cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, infile); jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); *width = cinfo.output_width; *height = cinfo.output_height; int num_channels = cinfo.output_components; buffer = (unsigned char*) malloc(*width * *height * num_channels); buffer_array = (JSAMPARRAY) malloc(sizeof(JSAMPROW) * *height); for (int i = 0; i < *height; i++) { buffer_array[i] = & buffer[i * *width * num_channels]; } row_stride = cinfo.output_width * cinfo.output_components; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, &buffer_array[cinfo.output_scanline], 1); } jpeg_finish_decompress(&cinfo); fclose(infile); jpeg_destroy_decompress(&cinfo); free(buffer_array); return buffer; } int main() { const char* filename = "test.jpg"; int width, height, quality = 80; unsigned char* image_buffer; // 编码 image_buffer = (unsigned char*) malloc(width * height * 3); encode_jpeg(filename, image_buffer, width, height, quality); // 解码 image_buffer = decode_jpeg(filename, &width, &height); free(image_buffer); return 0; } ``` 在上面的代码中,`encode_jpeg`函数用于对输入的RGB图像进行JPEG压缩编码,并将编码后的结果保存到指定的文件中。`decode_jpeg`函数用于对指定的JPEG文件进行解码,并返回解码后的RGB图像数据。在主函数中,我们首先调用`encode_jpeg`对指定的RGB图像进行编码,然后调用`decode_jpeg`对编码后的JPEG文件进行解码,最后释放图像数据的内存空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轻舞飞扬SR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值