内存中的bmp转换成内存中的jpg?

时间:2021-04-06 06:37:20
程序是用VC++ 6.0的MFC
内存中的bmp数据是用摄像头采集的,我要把它转化成jpg数据之后在网络上传输(不要存成文件,那样影响速度).
我有用过jpeg.lib库
里面有两个函数
extern "c"
{
void RGBtoJPEGBuff(BYTE* Buff,DWORD ImageWidth,DWORD ImageHeight,BYTE *outJPEGBuff,DWORD *BuffLen);
void RGBtoJPEGFile(BYTE* Buff,DWORD ImageWidth,DWORD ImageHeight,char* outFileName);
}
RGBtoJPEGFile这个我用过可以
RGBtoJPEGBuff这个也可以用,只是转换过后得到的内容有问题。
如:
RGBtoJPEGBuff(Buff1,ImageWidth,ImageHeight,outJPEGBuff1,DWORD *BuffLen1);
RGBtoJPEGBuff(Buff2,ImageWidth,ImageHeight,outJPEGBuff2,DWORD *BuffLen2);
outJPEGBuff2的内容=outJPEGBuff1的内容+我想要的buff2转换的实际内容(outJPEGBuff2+BuffLen1),也就是后面转换的会把前面所有转换过的累加进去,这是什么原因?怎样解决?

有没有什么其它的转换方法?(最好有原码)

25 个解决方案

#1


关注

#2


我跟你碰到的问题是一模一样一样,只要应用程序没有结束,只能转一个JPG,第二个,和后面就会累加起来
不知道你有没有解决这个问题

#3


还没解决,现在只好先转化成jpg文件了

有看过用gdi+,CImage什么的,没用过,不过好像都是.net的吧

#4


你准备用什么方法转换啊?
用CxImage好像好慢

#5


正在查找好的方法

我在网站上找到了一份压缩的原码
http://blog.csdn.net/dd167/archive/2006/02/16/600301.aspx
正如里面所说的
/*
 这是一个简单的jpeg编码程序,支持1:1:1采样的baseline彩色jpeg,输入只能是24bit的BMP文件
 代码结构只求能说明各步骤过程,并不做特别的优化,效率较为一般。
*/
我还发现了一些问题,就是压缩连续图像的时候,原图像没变化,压缩出来的图像却有时亮有时暗,有的时候左边会有一些跑到了右边,就是压缩很不稳定。
测试了一下时间,一帧差不多47ms,不知道速度和其它的一些方法比怎样?

#6


忘了说了,帧的大小是320*240像素

#7


顺便请教一下,RGBtoJPEGFile的Buff参数不知道该怎么设置,我是用CDC取得图像,然后用GetDIBits取得像素buffer,然后把这个buffer传给RGBtoJPEGFile,结果保存的jpg都花了,怎么回事呢?

#8


学习一下,蹭点分!

#9


难搞,顶下先

#10


最近我也有同样的问题得不到解决

#11


可以用INTEL的IJL15.DLL库来压缩,速度快占用资源少。
在压缩时可以设置压缩到内存或者压缩到文件,用IJL_JBUFF_WRITEWHOLEIMAGE就可以实现你的要求。

#12


可以用GDI+,可以不用.net.
vc 6.0完全可以调用,而且非常方便。

#13


到www.codeproject.com下载一个Ximage吧,很方便,很好用,而且免费

#14


友情接分

#15


我也推荐CXIMAGE

#16


学习中

#17


to:lhxx(随风)

有没有IJL的库和示例,发一份给我,谢谢
hiox_ppl@163.com

#18


不知道,帮顶

#19


CXIMAGE的Decode!

#20


大家说的可行方法,能不能把代码贴出来或发一份给我

#21


gdi+吧
http://blog.csdn.net/lixiaosan/archive/2006/04/28/694790.aspx
呵呵 抄来的

#22


还不如压成视频传输,特别是连续的时候

#23


回复楼主我已解决
内存中转换绝对可行
void Cmfc对话框Dlg::OnBnClickedButton3()
 {
        CImage mmage;
 HWND hWnd = ::GetDesktopWindow();//获得屏幕的HWND.
 HDC hScreenDC = ::GetDC(hWnd);   //获得屏幕的HDC.
 HDC MemDC = ::CreateCompatibleDC(hScreenDC);
 RECT rect; 
    
 ::GetWindowRect(hWnd,&rect);
 
 HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC,rect.right,rect.bottom);
 HGDIOBJ hOldBMP = ::SelectObject(MemDC,hBitmap);
 ::BitBlt(MemDC,0,0,rect.right,rect.bottom,hScreenDC,rect.left,rect.top,SRCCOPY);
 hBitmap=(HBITMAP)::SelectObject(MemDC,hOldBMP);
 
 mmage.Attach(hBitmap);
 IStream* pStmImage = NULL;
    
 HGLOBAL hMemBmp = GlobalAlloc(GMEM_MOVEABLE,0);//可移动的缓冲区
 if (hMemBmp == NULL) return;
 CreateStreamOnHGlobal(hMemBmp, FALSE, &pStmImage);//将内存区B作为流的起始
 if (pStmImage == NULL)

       {
              GlobalFree(hMemBmp);
              MessageBox(L"为空");
     return ;
       }
 mmage.Save(pStmImage,ImageFormatJPEG);

 BYTE* pbyBmp = (BYTE *)GlobalLock(hMemBmp);//得到缓冲区的起始地址
 
 CFile mfile(L"234.jpg",CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
 GlobalUnlock(hMemBmp);
 mfile.Write(pbyBmp,GlobalSize(hMemBmp));
 mfile.Close();
pStmImage->Release();
GlobalFree(hMemBmp);
if(mmage)
mmage.Destroy();
::DeleteObject(MemDC);
::ReleaseDC(hWnd,hScreenDC);}

#24


楼上的我试了一下,在vc++6.0里不行,在vc++.net里可以运行(做一点修改)
我得到的是24位的纯数据,你的方法应该要在数据前加上bmp头,形成完整的位图文件再转化吧

#25


不要在数据前加上bmp头,自动加上,我存的是JPG,有一些函数我没有写出可以到网上找到或在MSDN上找得到

#1


关注

#2


我跟你碰到的问题是一模一样一样,只要应用程序没有结束,只能转一个JPG,第二个,和后面就会累加起来
不知道你有没有解决这个问题

#3


还没解决,现在只好先转化成jpg文件了

有看过用gdi+,CImage什么的,没用过,不过好像都是.net的吧

#4


你准备用什么方法转换啊?
用CxImage好像好慢

#5


正在查找好的方法

我在网站上找到了一份压缩的原码
http://blog.csdn.net/dd167/archive/2006/02/16/600301.aspx
正如里面所说的
/*
 这是一个简单的jpeg编码程序,支持1:1:1采样的baseline彩色jpeg,输入只能是24bit的BMP文件
 代码结构只求能说明各步骤过程,并不做特别的优化,效率较为一般。
*/
我还发现了一些问题,就是压缩连续图像的时候,原图像没变化,压缩出来的图像却有时亮有时暗,有的时候左边会有一些跑到了右边,就是压缩很不稳定。
测试了一下时间,一帧差不多47ms,不知道速度和其它的一些方法比怎样?

#6


忘了说了,帧的大小是320*240像素

#7


顺便请教一下,RGBtoJPEGFile的Buff参数不知道该怎么设置,我是用CDC取得图像,然后用GetDIBits取得像素buffer,然后把这个buffer传给RGBtoJPEGFile,结果保存的jpg都花了,怎么回事呢?

#8


学习一下,蹭点分!

#9


难搞,顶下先

#10


最近我也有同样的问题得不到解决

#11


可以用INTEL的IJL15.DLL库来压缩,速度快占用资源少。
在压缩时可以设置压缩到内存或者压缩到文件,用IJL_JBUFF_WRITEWHOLEIMAGE就可以实现你的要求。

#12


可以用GDI+,可以不用.net.
vc 6.0完全可以调用,而且非常方便。

#13


到www.codeproject.com下载一个Ximage吧,很方便,很好用,而且免费

#14


友情接分

#15


我也推荐CXIMAGE

#16


学习中

#17


to:lhxx(随风)

有没有IJL的库和示例,发一份给我,谢谢
hiox_ppl@163.com

#18


不知道,帮顶

#19


CXIMAGE的Decode!

#20


大家说的可行方法,能不能把代码贴出来或发一份给我

#21


gdi+吧
http://blog.csdn.net/lixiaosan/archive/2006/04/28/694790.aspx
呵呵 抄来的

#22


还不如压成视频传输,特别是连续的时候

#23


回复楼主我已解决
内存中转换绝对可行
void Cmfc对话框Dlg::OnBnClickedButton3()
 {
        CImage mmage;
 HWND hWnd = ::GetDesktopWindow();//获得屏幕的HWND.
 HDC hScreenDC = ::GetDC(hWnd);   //获得屏幕的HDC.
 HDC MemDC = ::CreateCompatibleDC(hScreenDC);
 RECT rect; 
    
 ::GetWindowRect(hWnd,&rect);
 
 HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC,rect.right,rect.bottom);
 HGDIOBJ hOldBMP = ::SelectObject(MemDC,hBitmap);
 ::BitBlt(MemDC,0,0,rect.right,rect.bottom,hScreenDC,rect.left,rect.top,SRCCOPY);
 hBitmap=(HBITMAP)::SelectObject(MemDC,hOldBMP);
 
 mmage.Attach(hBitmap);
 IStream* pStmImage = NULL;
    
 HGLOBAL hMemBmp = GlobalAlloc(GMEM_MOVEABLE,0);//可移动的缓冲区
 if (hMemBmp == NULL) return;
 CreateStreamOnHGlobal(hMemBmp, FALSE, &pStmImage);//将内存区B作为流的起始
 if (pStmImage == NULL)

       {
              GlobalFree(hMemBmp);
              MessageBox(L"为空");
     return ;
       }
 mmage.Save(pStmImage,ImageFormatJPEG);

 BYTE* pbyBmp = (BYTE *)GlobalLock(hMemBmp);//得到缓冲区的起始地址
 
 CFile mfile(L"234.jpg",CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
 GlobalUnlock(hMemBmp);
 mfile.Write(pbyBmp,GlobalSize(hMemBmp));
 mfile.Close();
pStmImage->Release();
GlobalFree(hMemBmp);
if(mmage)
mmage.Destroy();
::DeleteObject(MemDC);
::ReleaseDC(hWnd,hScreenDC);}

#24


楼上的我试了一下,在vc++6.0里不行,在vc++.net里可以运行(做一点修改)
我得到的是24位的纯数据,你的方法应该要在数据前加上bmp头,形成完整的位图文件再转化吧

#25


不要在数据前加上bmp头,自动加上,我存的是JPG,有一些函数我没有写出可以到网上找到或在MSDN上找得到