实现从内存中解压JPEG
来源:互联网 发布:淘宝优惠券转化器 编辑:程序博客网 时间:2024/06/05 03:19
一、简介
Jpeg编解码的程序网络上有很多,也有很多现成的类如著名的CxImage,或者使用OpenCV。但是这些ToolTik基本上都只提供了从硬盘打开JPEG图像进行解码,有的时候如果JPEG的图像数据是从内存载入的,就无法使用这些曾经很方便高效的接口。比如OpenCV提供的接口是:CVAPI(IplImage*) cvLoadImage( const char* filename, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR));
二、解决的办法:
- 用ramdisk内存虚拟硬盘,把传输过来的jpg文件存在虚拟盘,再用cvLoadImage载入分析.
- OpenCV 2.0 提供该功能。(我装的是OpenCV 1.1,还没用过这两个函数)
imdecode
Mat imdecode( const Mat& buf, int flags );
buf The input array of vector of bytes
flags The same flags as in imread
The function reads image from the specified buffer in memory. If the buffer is too short or
contains invalid data, the empty matrix will be returned.
See imread for the list of supported formats and the flags description.
imencode
bool imencode( const string& ext, const Mat& img,
vector<uchar>& buf,
const vector<int>& params=vector<int>());
ext The file extension that defines the output format
img The image to be written
buf The output buffer; resized to fit the compressed image
params The format-specific parameters; see imwrite
The function compresses the image and stores it in the memory buffer, which is resized to fit
the result. See imwrite for the list of supported formats and the flags description. - 看了网上的一些代码,我使用JpegLib改了一个接口。opencv中也有JpegLib,如果要使用opencv中的JpegLib注意配置HAVE_JPEG。我把这个接口放到了OpenCV中,这样做是为了一劳永逸,其他工程要用到这个接口时不需要复制粘贴。
首先在highgui.h中做函数声明
/**********************************************************************/
// by xjf 2009-11-09
// convert a jpeg image to bmp from a buffer
// cause we can use opencv to convert a jpeg image from file by easily
// using cvLoadImage()
// the api in the grfmt_jpeg.cpp
CVAPI(IplImage*) cvJpeg2Ipl(char *jpegData, int jpegSize);
函数的实现我放到了grfmt_jpeg.cpp
/**********************************************************************/
void mem_init_source(j_decompress_ptr cinfo)
{
// cinfo->src->bytes_in_buffer = g_buf_len;
// cinfo->src->next_input_byte = (unsigned char*)g_buf;
}
boolean mem_fill_input_buffer(j_decompress_ptr cinfo)
{
return true;
}
void mem_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
cinfo->src->bytes_in_buffer -= num_bytes;
cinfo->src->next_input_byte += num_bytes;
}
boolean mem_resync_to_restart(j_decompress_ptr cinfo, int desired)
{
return jpeg_resync_to_restart(cinfo, desired);
}
void mem_term_source(j_decompress_ptr cinfo)
{
}
/**********************************************************************/
// @jpegData: 内存中的JPEG图像数据流
// @jpegSize:数据流大小
CV_IMPL IplImage*
cvJpeg2Ipl(char *jpegData, int jpegSize)
{
IplImage *_pImg = 0;
jpeg_source_mgr jmgr;
struct jpeg_error_mgr jerr;
struct jpeg_decompress_struct cinfo;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jmgr.init_source = mem_init_source;
jmgr.fill_input_buffer = mem_fill_input_buffer;
jmgr.skip_input_data = mem_skip_input_data;
jmgr.resync_to_restart = mem_resync_to_restart;
jmgr.term_source = mem_term_source;
jmgr.next_input_byte = (unsigned char*)jpegData;
jmgr.bytes_in_buffer = jpegSize;
cinfo.src = &jmgr;
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
int nRowSize = cinfo.output_width * cinfo.output_components;
int w =cinfo.output_width;
int h =cinfo.output_height;
char *bmpBuffer=new char[h*w*3];
JSAMPARRAY pBuffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, 1, nRowSize, 1);
while(cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, pBuffer, 1);
int start=nRowSize*(cinfo.output_scanline-1);
for(int i=0;i<nRowSize;i++)
{
bmpBuffer[start+i]=pBuffer[0][i];
}
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
_pImg = cvCreateImage(cvSize(w,h),8,3);
for (h=0; h<_pImg->height; h++)
{
for (w=0; w<_pImg->widthStep; w+=3)
{
*(_pImg->imageData+h*_pImg->widthStep+w+0)=*(bmpBuffer+h*_pImg->widthStep+w+2);
*(_pImg->imageData+h*_pImg->widthStep+w+1)=*(bmpBuffer+h*_pImg->widthStep+w+1);
*(_pImg->imageData+h*_pImg->widthStep+w+2)=*(bmpBuffer+h*_pImg->widthStep+w+0);
}
}
delete bmpBuffer;
bmpBuffer=NULL;
return _pImg;
}
需重新编译opencv
- 实现从内存中解压JPEG
- 实现从内存中解压JPEG
- arm摄像头获取jpeg图像后,从内存中解压jpeg图像,并用openCV处理
- 在VC上实现如何从内存中读取JPEG、GIF等图像
- 在VC上实现如何从内存中读取JPEG、GIF等图像
- 在VC上实现如何从内存中读取JPEG、GIF等图像
- 在VC上实现如何从内存中读取JPEG、GIF等图像
- JPEG解压
- JPEG图像压缩解压算法——C++实现
- 压缩解压库,内存中解压
- 利用GDI+ 从内存读取jpeg,画到窗口。
- 不修改源代码实现Libjpeg内存编解码jpeg
- CImage实现jpeg到bmp内存图像转换
- 3、lib7z-Memory从内存或网络解压数据(7z内存解压完成)
- 从rpm包中解压文件
- 从rpm包中解压文件
- 从EXIF JPEG图片中提取GPS位置信息
- C#如何实现从内存中加载程序集
- x86和x64
- Android之涂鸦(简单的画图)
- 如何在ActiveRecord自动化记录时间戳
- win32 api 文件操作
- InstallSheild 拷贝文件夹
- 实现从内存中解压JPEG
- Android调用系统短信发送界面并预设接收号码、短信内容
- MOSFET与MOSFET驱动电路原理及应用
- SQLiteOpenHelper简介
- OnClick,OnClientClick和OnServerClick的区别
- 里程碑
- Hibernate性能优化之————延迟加载与抓取策略
- EZ Gui创建ScrollList(滚动列表)
- MOSFET驱动电路应用实例