一、libjpeg-turbo简介
libjpeg-turbo是一个基于libjpeg的高性能JPEG压缩库,它在压缩率与速度之间做了平衡,并取得了非常不错的效果。它采用了SIMD指令集,通过使用从x86、MIPS和ARM架构中挑选出的最优指令,进一步提高了执行效率。
接下来,我们将通过一个代码示例来体验它的压缩速度与压缩率。
#include#include void compress(const char *filename_in, const char *filename_out, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; int row_stride; FILE *infile = fopen(filename_in, "rb"); unsigned char *buffer; if (!infile) { printf("can't open %s\n", filename_in); return; } buffer = (unsigned char *)malloc(1 << 20); // 1MB if (!buffer) { printf("not enough memory\n"); fclose(infile); return; } fseek(infile, 0, SEEK_END); size_t file_size = ftell(infile); fseek(infile, 0, SEEK_SET); fread(buffer, 1, file_size, infile); fclose(infile); cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); FILE *outfile = fopen(filename_out, "wb"); if (!outfile) { printf("can't open %s\n", filename_out); jpeg_destroy_compress(&cinfo); return; } jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = 3840; cinfo.image_height = 2160; 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 = cinfo.image_width * 3; while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & buffer[cinfo.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); fclose(outfile); jpeg_destroy_compress(&cinfo); printf("%s compressed to %s (quality=%d)\n", filename_in, filename_out, quality); } int main(int argc, char *argv[]) { compress("test.jpg", "test_compressed.jpg", 80); return 0; }
在上面这段代码中,我们定义了一个名为compress的函数用于压缩JPEG文件。我们调用该函数时需要提供三个参数:输入文件名、输出文件名和压缩质量。其中,输入文件名指的是需要压缩的JPEG图片,输出文件名指的是压缩完成后的JPEG图片,压缩质量则是一个0~100的整数,0表示压缩质量最差,100表示压缩质量最好。
在上述示例代码中,我们将一张分辨率为3840x2160的JPEG图片进行了80%的压缩,并输出到了另一个文件中。当然,我们可以对比不同的压缩质量所获得的压缩率和压缩时间,以便更好地权衡压缩质量与速度。
二、libjpeg-turbo的优势
那么,为什么应该选择使用libjpeg-turbo呢?首先,它显著提高了压缩速度,这使得它成为了许多应用场景下的首选。此外,它还允许用户选择更高的压缩率,使得压缩后的图片质量更高。
应用libjpeg-turbo还有一个优势,那就是它可以支持许多操作系统和平台,包括Linux、Windows、Mac OS X和Android等。
下面这段代码演示了如何在Android平台上使用libjpeg-turbo:
#include#include #include #define LOG_TAG "libjpeg-turbo" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) void compress(const char *filename_in, const char *filename_out, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; int row_stride; FILE *infile = fopen(filename_in, "rb"); unsigned char *buffer; if (!infile) { LOGE("can't open %s", filename_in); return; } buffer = (unsigned char *)malloc(1 << 20); // 1MB if (!buffer) { LOGE("not enough memory"); fclose(infile); return; } fseek(infile, 0, SEEK_END); size_t file_size = ftell(infile); fseek(infile, 0, SEEK_SET); fread(buffer, 1, file_size, infile); fclose(infile); cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); FILE *outfile = fopen(filename_out, "wb"); if (!outfile) { LOGE("can't open %s", filename_out); jpeg_destroy_compress(&cinfo); return; } jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = 3840; cinfo.image_height = 2160; 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 = cinfo.image_width * 3; while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & buffer[cinfo.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); fclose(outfile); jpeg_destroy_compress(&cinfo); LOGI("%s compressed to %s (quality=%d)", filename_in, filename_out, quality); } int main(int argc, char *argv[]) { // 在Android平台上,可以使用以下代码来获取应用的路径 // 并将要压缩的图片路径拼接上去 char *path_to_image = "/data/data/com.example.myapp/files/test.jpg"; char *path_to_compressed_image = "/data/data/com.example.myapp/files/test_compressed.jpg"; int quality = 80; // 压缩质量 compress(path_to_image, path_to_compressed_image, quality); return 0; }
上述示例代码展示了在Android平台上使用libjpeg-turbo进行图片压缩的方法。通过使用ANRDOID_LOG_INFO和ANDROID_LOG_ERROR宏来输出调试信息,我们可以更方便地确定在压缩过程中可能出现的问题所在。
三、总结
本文中,我们详细阐述了libjpeg-turbo的应用与优势,并且通过代码示例演示了如何使用libjpeg-turbo进行高效的图像压缩。同时,我们还探讨了如何在不同的操作系统和平台上使用libjpeg-turbo。相信这些内容对于开发者们的图像处理工作有所帮助。