2010-06-13 13:22:21
首先jpeg.lib必须有,还要包含jconfig.h,jmorecfg.h,jpeglib.h。
#include "jpeglib.h"
==================
提示:
转JPG时,数据要求4字节对齐,数据流用如下函数补齐。
//in: nBits = Width * nDepthBits
int ByteAlign( int nBits )
{
int nAlignBytes = ( nBits + 31 ) / 32 * 4;
return nAlignBytes;
}
==================
/*encode BMP24 into JPEG
use jpeg-lib 8.0
parameter:
BYTE *pRGB24In [in] RGB24 的BMP 数据,不包含头信息;
int nWidth [in] BMP 图像的宽度(像素);
int nHight [in] BMP 图像的高度(像素);
int nLineBytes [in] BMP 图像的每行的字节数(必须4字节对齐,如没有对齐需要补齐);
BYTE *pJpgOut [out] 转换成JPG的数据
return: 压缩为JPG后的数据大小
Note: pJpgOut 会在函数内部进行内存分配,使用此函数后需要释放内存
nCompressed 0---100之间,表示图像压缩率,建议75
*/
int JpegFromBMP24(BYTE *pRGB24In, int nWidth, int nHeight, int nLineBytes, LPBYTE &pJpgOut);
{
struct jpeg_compress_struct jcs;
struct jpeg_error_mgr jsrcerr;
if (pRGB24In == NULL)
return 0;
if (nWidth == 0)
return 0;
if (nHeight == 0)
return 0;
/* initialize the JPEG compression object. */nCompressed
jcs.err = jpeg_std_error(&jsrcerr);
jpeg_create_compress(&jcs);
unsigned long lsize = 0;
BYTE* lpJpgData = NULL;
jpeg_mem_dest(&jcs, &lpJpgData, &lsize);
jcs.image_width = nWidth; /* image widthPix and height, in pixels */
jcs.image_height = nHeight;
jcs.input_components = 3; /* # of color components per pixel */
jcs.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&jcs);
int nCompressed = 71; /*[0-100], if 0, quality is best, but size is biggest*/
jpeg_set_quality(&jcs, nCompressed, TRUE /* limit to baseline-JPEG values */);
jpeg_start_compress(&jcs, TRUE);
while (jcs.next_scanline < jcs.image_height)
{
LPBYTE outRow;
int nRow = jcs.image_height - jcs.next_scanline - 1;//last to header
int offset = nRow * nLineBytes;
outRow = pRGB24In + offset;
for(int index=0; index < nLineBytes/3; index++)
{
int nRGBbit = index * 3;
BYTE tmp;
tmp = *(outRow + nRGBbit + 0);
*(outRow + nRGBbit + 0) = *(outRow + nRGBbit + 2);//r = g
*(outRow + nRGBbit + 2) = tmp;//g = r
}
(void) jpeg_write_scanlines(&jcs, &outRow, 1);
}
jpeg_finish_compress(&jcs);
jpeg_destroy_compress(&jcs);
if(pJpgOut == NULL)
{
pJpgOut = (LPBYTE)malloc(lsize);
memset(pJpgOut, 0, lsize);
}
memcpy(pJpgOut, lpJpgData, lsize);
if( lpJpgData != NULL )
free( lpJpgData );
return lsize;
}
BOOL JpegToBMP24( BYTE *pJpgIn, int nJPGDataSize, LPBYTE& pRGB24Out, int& nWidth, int& nHight, int& nLineBytes )
{
if (pJpgIn ==NULL)
return FALSE;
struct jpeg_decompress_struct jds;
struct jpeg_error_mgr jdsterr;
jds.err = jpeg_std_error(&jdsterr);
jpeg_create_decompress(&jds);
jpeg_mem_src(&jds, pJpgIn, nJPGDataSize);
(void) jpeg_read_header(&jds, TRUE);
jpeg_start_decompress(&jds);
nWidth = jds.output_width;
nHight = jds.output_height;
nLineBytes = ByteAlign( nWidth * 24 );
JSAMPARRAY buffer; /* Output row buffer */
int row_width;
/* SAMPLEs per row in output buffer */
row_width = jds.output_width * jds.output_components;
buffer = (*jds.mem->alloc_sarray)
((j_common_ptr) &jds, JPOOL_IMAGE, nLineBytes, 1);
if(pRGB24Out == NULL)
{
int dataSize = (nLineBytes) * (nHight);
pRGB24Out = (LPBYTE)malloc(dataSize);
memset(pRGB24Out, 0, dataSize);
}
while (jds.output_scanline < jds.output_height)
{
(void) jpeg_read_scanlines(&jds, buffer, 1);
if (jds.out_color_components==3)
{
JPGputRGBScanline(buffer[0], nWidth, pRGB24Out, jds.output_height-jds.output_scanline);
}
}
jpeg_finish_decompress(&jds);
jpeg_destroy_decompress(&jds);
return TRUE;
}
exsample:
void func(CString strFileName)
{
/*BMP data to JPG */
HBITMAP hBitmap = NULL;
hBitmap = ( HBITMAP )LoadImage( NULL, strFileName, IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE | LR_SHARED );
CBitmap pRGB16Bmp;
pRGB16Bmp.Detach();
pRGB16Bmp.Attach( hBitmap );
BITMAP *pBitMap = new BITMAP;
pRGB16Bmp.GetBitmap( pBitMap );
int nWidth = pBitMap->bmWidth;
int nSrcColorBits = (int)(pBitMap->bmBitsPixel);
int nSrcBitsPiexel = 0;
switch( nSrcColorBits)
{
case 16:
nSrcBitsPiexel = 2;
break;
case 24:
nSrcBitsPiexel = 3;
break;
case 32:
nSrcBitsPiexel = 4;
break;
default
nSrcBitsPiexel = 3;
break;
}
int nSrcLineBytes = ByteAlign( nWidth * nSrcBitsPiexel * 8 );//字节对齐
BYTE *pJpgOut = NULL;
int nSize = JpegFromBMP24( pBitMap->bmBits, nWidth, nHeight, nSrcLineBytes, pJpgOut);
FILE *hFile = fopen("C://test.jpg","wb");
fwrite(pJpgOut,sizeof(unsigned char),nSize,hFile);
fclose(hFile);
/*JPG data to BMP*/
if( nSrcColorBits == 16 ||
nSrcColorBits == 32 )
{
nDstBitsPiexel = 3;
}
else if( nSrcColorBits == 24 )
{
nDstBitsPiexel = 2;
}
else //default
{
nDstBitsPiexel = 2;
}
int nDstLineBytes = ByteAlign( nWidth*nDstBitsPiexel*8 );
JpegToBMP24( pJpgOut, nSize, pRGB24Out, nWidth, nHeight, nDstLineBytes );
//SavetoBmp(...)
//parament : pRGB24Out, nWidth, nHeight, "C://test.bmp",.......
}