图片在jpg 格式与bmp24格式之间的转换

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",.......

}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值