【发布时间】:2023-12-06 08:19:02
【问题描述】:
我正在尝试使用来自 ijg 的 libjpeg 将 RGB 图像压缩为 JPEG。最后的想法是使用图像传感器拍摄图像并将数据压缩为 ARM Cortex M3 控制器上的 JPEG;但是,出于测试目的,我一直在使用使用 GIMP 转换为 RGB .data 文件的 BMP 文件。
我已经能够使用控制器和 libjpeg 成功地将 RGB 数据压缩到 SD 卡上的 JPEG 图像中,但是使用这种方法我看到图像上有一条扭曲的线,我不确定是什么原因造成的,以及如何解决它。
这是压缩后的 JPEG 图片:http://i.imgur.com/kFBEhEs.jpg
这是源 BMP 图像:http://i.imgur.com/jenHG0b.png
这里是相关代码sn-ps:
static uint8_t* _pucImageSrc ;
static uint8_t* _pucImageDst ;
static uint8_t*_pucCapturedBuf;
uint8_t _compress_image_jpg(SJPEGTest *pImage, sdCardDataHandler *datahandler){
SJpegData sJpegData;
_pucImageDst=malloc(datahandler->sourceSize);
_pucCapturedBuf = datahandler->sourcePtr;
pImage->dwTimeC=getTicks();
JpegData_Init( &sJpegData ) ;
JpegData_SetSource( &sJpegData, _pucCapturedBuf, datahandler->sourceSize) ;
JpegData_SetDestination( &sJpegData, _pucImageDst, datahandler->sourceSize ) ;
JpegData_SetDimensions( &sJpegData, 512, 384, 3 ) ;
JpegData_SetParameters( &sJpegData, 25, JPG_DATA_RGB, JPG_METHOD_IFAST ) ;
if ( ijg_compress( &sJpegData ) == 0 ){
pImage->dwTimeC=1+getTicks()-pImage->dwTimeC;
pImage->dwFinalLength=sJpegData.dwDstLength;
pImage->dwTimeD=getTicks();
} else {
return JPEG_CONVERSION_ERRORED;
}
datahandler->destSize = sJpegData.dwDstLength;
datahandler->destPtr = _pucImageDst;
return JPEG_CONVERSION_COMPLETE;
}
extern uint32_t ijg_compress( SJpegData* pData ){
struct jpeg_compress_struct cinfo ;
struct my_error_mgr jerr ;
JSAMPROW row_pointer ; /* pointer to a single row */
assert( pData != NULL ) ;
cinfo.err = jpeg_std_error( &jerr.pub ) ;
if(setjmp(jerr.setjmp_buffer)){
jpeg_destroy_compress(&cinfo);
return 1;
}
jpeg_create_compress( &cinfo ) ;
jpeg_mem_dest( &cinfo, &(pData->pucDst), (unsigned long*)&(pData->dwDstLength) ) ;
cinfo.image_width = pData->dwWidth ;
cinfo.image_height = pData->dwHeight ;
cinfo.input_components = pData->dwBPP ;
cinfo.in_color_space = pData->eInput ;
jpeg_set_defaults( &cinfo ) ;
cinfo.dct_method = pData->eMethod ;
jpeg_set_quality( &cinfo, pData->dwQuality, true ) ;
jpeg_start_compress( &cinfo, true ) ;
while ( cinfo.next_scanline < cinfo.image_height )
{
row_pointer = (JSAMPROW) &pData->pucSrc[cinfo.next_scanline*cinfo.image_width*cinfo.input_components] ;
jpeg_write_scanlines( &cinfo, &row_pointer, 1 ) ;
}
jpeg_finish_compress( &cinfo ) ;
jpeg_destroy_compress(&cinfo);
return 0 ;
}
【问题讨论】:
-
你检查解码器示例了吗?
-
在 libjeg 的 example.c 中,我一直在查看 write_JPEG_file 函数。上述示例中的一些函数调用似乎来自从 Atmel 的 SAM3S PIRRD jpeg 压缩应用笔记和库中提取的 libjpeg 库。我没有使用 SAM3S 控制器,而是使用 SAM3U 控制器。从这两个参考资料中,我已经达到了帖子中描述的要点。
-
看起来您的源图像数据是问题的根源。压缩数据的任何损坏都可能导致从那时起图像的其余部分完全无用。如果您不使用重新启动标记,那么在发生错误后几乎没有办法重新同步。将 bmp 文件加载到内存后,看起来好像有一些东西正在写入图像缓冲区。
-
我将尝试验证我们是否在将数据加载到内存后损坏了数据,但我怀疑情况是否如此,因为我们正在运行一个仅用作堆的外部 RAM 芯片读入的原始数据和来自 libjpeg 的压缩 jpeg 数据,并通过 malloc 分配。