理论上使用 turbojpeg 更快,但我的测试结果恰恰相反。结果:
the size of jpg: 5040*5216
opencv: 4.2.0
quailty : 100
sample: 4:2:0
use fastdct
使用 OpenCV imencode:38.78 毫秒
使用涡轮解压:87.5 毫秒
以下是我的代码:
// support jpg to bmp/ppm/pgm
bool jpg2bmp_turbo(char * jpg_file_path, char * bmp_dst_path, int height, int width)
{
if (height == 0) return false;
tjscalingfactor scalingFactor = { 1, 1 };
int flags = TJFLAG_FASTDCT;
FILE *jpegFile = NULL;
unsigned char *imgBuf = NULL, *jpegBuf = NULL;
int pixelFormat = TJPF_UNKNOWN;
tjhandle tjInstance = NULL;
long size;
int inSubsamp, inColorspace;
unsigned long jpegSize;
/* Read the JPEG file into memory. */
jpegFile = fopen(jpg_file_path, "rb");
fseek(jpegFile, 0, SEEK_END);
size = ftell(jpegFile);
fseek(jpegFile, 0, SEEK_SET);
jpegSize = (unsigned long)size;
jpegBuf = (unsigned char *)tjAlloc(jpegSize);
fread(jpegBuf, jpegSize, 1, jpegFile);
tjInstance = tjInitDecompress();
pixelFormat = TJPF_BGRX;
imgBuf = (unsigned char *)tjAlloc(width * height * tjPixelSize[pixelFormat]);
tjDecompressHeader3(tjInstance, jpegBuf, jpegSize, &width, &height,
&inSubsamp, &inColorspace);
std::chrono::time_point<std::chrono::steady_clock> start, end;
start = std::chrono::steady_clock::now();
tjDecompress2(tjInstance, jpegBuf, jpegSize, imgBuf, width, 0, height,
pixelFormat, flags);
end = std::chrono::steady_clock::now();
std::chrono::duration<double, std::milli> elapsed_time = end - start;
std::cout << "turbo uncompress jpg to bmp: " << elapsed_time.count() << std::endl;
/* Output image */
tjSaveImage(bmp_dst_path, imgBuf, width, 0, height, pixelFormat, 0);
tjFree(imgBuf);
tjDestroy(tjInstance);
tjFree(jpegBuf);
fclose(jpegFile);
return true;
}
这是主要功能
int main()
{
std::chrono::time_point<std::chrono::steady_clock> start, end;
std::chrono::duration<double, std::milli> elapsed_time;
std::vector<int> param(2);
// turbo jpg to bmp/ppm/pgm
char jpgfile_src[] = "/test_data/input/map.jpg";
char bmpfile_dst[] = "/test_data/output/jpg_bmp_map_turbo.bmp";
jpg2bmp_turbo(jpgfile_src, bmpfile_dst, 5216, 5040);
// opencv jpg to bmp
std::string jpgfile = "/test_data/input/map.jpg";
cv::Mat cv_jpg = cv::imread(jpgfile, cv::IMREAD_UNCHANGED);
std::vector<uchar> jpgbuffer;
start = std::chrono::steady_clock::now();
cv::imencode(".bmp", cv_jpg, jpgbuffer, std::vector<int>());
end = std::chrono::steady_clock::now();
elapsed_time = end - start;
std::cout << "opencv encode jpg to bmp: " << elapsed_time.count() << std::endl;
return 0;
}
Libjpeg-turbo 被官方证明要快 2 到 6 倍。 https://libjpeg-turbo.org/About/Performance