ComImage

来源:互联网 发布:远程桌面登陆软件 编辑:程序博客网 时间:2024/04/30 09:39
//#include "StdAfx.h"
#include <Windows.h>
#include 
<stdlib.h>
#include 
<stdio.h>
#include 
"ComImage.h"
#include 
"ComFun.h"

HANDLE DDBToDIB(HBITMAP hBitmap, HPALETTE hPalette, BITMAPINFO 
* pOutDibInfo, int nBitpPix)
{
    BITMAP            BM;
    BITMAPINFOHEADER    BMinfoh;
    BITMAPINFO 
*        pBMinfo;
    HPALETTE        hPalOld 
= NULL;
    DWORD            dwLenDib, dwBmInfoLen;
    HANDLE            hDIB;
    HDC             hDC;
    
int                nColors;
    BOOL            bRetVal;
    
if(hBitmap == NULL)
    {
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return NULL;
    }
    
if (hPalette==NULL)
        hPalette 
= (HPALETTE)::GetStockObject(DEFAULT_PALETTE);
    GetObject(hBitmap, 
sizeof(BITMAP), (LPVOID)&BM);
    BMinfoh.biSize            
= sizeof(BITMAPINFOHEADER);
    BMinfoh.biWidth            
= BM.bmWidth;
    BMinfoh.biHeight         
= BM.bmHeight;
    BMinfoh.biPlanes         
= 1;        //Must 1
    if(nBitpPix == 0)
        BMinfoh.biBitCount        
= BM.bmPlanes * BM.bmBitsPixel;
    
else
        BMinfoh.biBitCount        
= BM.bmPlanes * nBitpPix;
    BMinfoh.biCompression    
= BI_RGB;
    BMinfoh.biSizeImage        
= 0;
    BMinfoh.biXPelsPerMeter    
= 0;
    BMinfoh.biYPelsPerMeter    
= 0;
    BMinfoh.biClrUsed        
= 0;
    BMinfoh.biClrImportant    
= 0;
    
if(BMinfoh.biBitCount > 8)        nColors = 0;
    
else                            nColors = 1 << BMinfoh.biBitCount;
    dwBmInfoLen  
= BMinfoh.biSize + nColors * sizeof(RGBQUAD);
    hDC 
= GetDC(NULL);
    
if(hPalette)
    {
        hPalOld 
= SelectPalette(hDC, hPalette, FALSE);
        RealizePalette(hDC);
    }

    pBMinfo 
= (BITMAPINFO *)GlobalAlloc(GMEM_FIXED, dwBmInfoLen);
    
if(pBMinfo == NULL)
    {
        SelectPalette(hDC, hPalOld, FALSE);
        ReleaseDC(NULL, hDC);
        ::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        
return NULL;
    }
    memcpy(
&pBMinfo->bmiHeader, &BMinfoh, sizeof(BITMAPINFOHEADER));
    GetDIBits(hDC, hBitmap, 
0, BMinfoh.biHeight, NULL, pBMinfo, DIB_RGB_COLORS);
    
if (pBMinfo->bmiHeader.biSizeImage == 0)
    {
        pBMinfo
->bmiHeader.biSizeImage = ((((pBMinfo->bmiHeader.biWidth * pBMinfo->bmiHeader.biBitCount) + 31& ~31/ 8
            
* pBMinfo->bmiHeader.biHeight;
    }
    dwLenDib 
= dwBmInfoLen + pBMinfo->bmiHeader.biSizeImage;
    hDIB 
= GlobalAlloc(GMEM_FIXED, dwLenDib);
    
if (hDIB == NULL)
    {
        GlobalFree(pBMinfo);
        
if(hPalOld)    SelectPalette(hDC, hPalOld, FALSE);
        ReleaseDC(NULL, hDC);
        
return NULL;
    }
    memcpy(hDIB, pBMinfo, 
sizeof(BITMAPINFOHEADER));
    bRetVal 
= GetDIBits(hDC, hBitmap, 0, BMinfoh.biHeight,
        (LPBYTE)hDIB 
+ (BMinfoh.biSize + nColors * sizeof(RGBQUAD)),
        pBMinfo, DIB_RGB_COLORS);
    
if( bRetVal == FALSE )
    {
        GlobalFree(hDIB);
        GlobalFree(pBMinfo);
        
if(hPalOld)    SelectPalette(hDC, hPalOld, FALSE);
        ReleaseDC(NULL, hDC);
        
return NULL;
    }
    
if(pOutDibInfo != NULL)
        memcpy(pOutDibInfo, pBMinfo, dwBmInfoLen);
    GlobalFree(pBMinfo);
    
if(hPalOld)    SelectPalette(hDC, hPalOld, FALSE);
    ReleaseDC(NULL, hDC);
    
return hDIB;
}

BOOL SaveDIBToBMP(HANDLE hDib, CHAR 
* pFileName)
{
    BITMAPFILEHEADER    BmFileHead;
    BITMAPINFOHEADER 
*    pBmInfoHead;
    
int                    nColors;
    HANDLE                hFile;
    DWORD                dwWrite;
    DWORD                dwDibSize;
    
if (!hDib)
    {
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return FALSE;
    }
    hFile 
= CreateFileA(pFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL 
| FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    
if (hFile == INVALID_HANDLE_VALUE)
    {
        
return FALSE;
    }
    pBmInfoHead 
= (BITMAPINFOHEADER *)hDib;
    
if(pBmInfoHead->biBitCount > 8)        nColors = 0;
    
else                                nColors = 1 << pBmInfoHead->biBitCount;
    dwDibSize 
= pBmInfoHead->biSize + nColors*sizeof(RGBQUAD) + pBmInfoHead->biSizeImage;
    BmFileHead.bfType        
= ((WORD) ('M' << 8| 'B');    //"BM"
    BmFileHead.bfSize        = dwDibSize + sizeof(BITMAPFILEHEADER);
    BmFileHead.bfReserved1    
= 0;
    BmFileHead.bfReserved2    
= 0;
    BmFileHead.bfOffBits    
= (DWORD) (sizeof( BITMAPFILEHEADER ) + pBmInfoHead->biSize + nColors * sizeof(RGBQUAD));
    WriteFile(hFile, 
&BmFileHead, sizeof(BITMAPFILEHEADER), &dwWrite, NULL);
    WriteFile(hFile, hDib,        dwDibSize,                
&dwWrite, NULL);
    CloseHandle(hFile);
    
return TRUE;
}

BOOL SaveBitmapToFile(HBITMAP hBitmap, CHAR 
* pFileName)
{
    HANDLE        hDib 
= NULL;
    HPALETTE    hPalette 
= NULL;
    BOOL        bRetVal;
    hDib 
= DDBToDIB(hBitmap, hPalette);
    
if(hDib == NULL)
    {
        
return FALSE;
    }
    bRetVal 
= SaveDIBToBMP(hDib, pFileName);
    GlobalFree(hDib);
    
return bRetVal;
}

HANDLE GetDIBFromWindow(HWND hWnd, RECT 
* pWndRect)
{
    HANDLE        hDib;
    HBITMAP        hBitmap, hOldBitmap;
    HDC            hWndDc, hMemDc;
    RECT        WndRect;
    
int            nWidth, nHeigh;
    hWndDc 
= ::GetWindowDC(hWnd);
    hMemDc 
= ::CreateCompatibleDC(hWndDc); 
    
if (pWndRect == NULL)
    {
        
if(hWnd == HWND_DESKTOP)
        {
            nWidth    
= GetSystemMetrics(SM_CXSCREEN);
            nHeigh    
= GetSystemMetrics(SM_CYSCREEN);
        }
        
else
        {
            ::GetWindowRect(hWnd, 
&WndRect);
            nWidth 
= WndRect.right - WndRect.left;
            nHeigh 
= WndRect.bottom - WndRect.top;
        }
    }
    
else
    {
        nWidth 
= pWndRect->right - pWndRect->left;
        nHeigh 
= pWndRect->bottom - pWndRect->top;
    }

    hBitmap 
= ::CreateCompatibleBitmap(hWndDc, nWidth, nHeigh);
    hOldBitmap 
= (HBITMAP)::SelectObject(hMemDc, hBitmap);
    BitBlt(hMemDc, 
00, nWidth, nHeigh, hWndDc, 00, SRCCOPY);
    hDib 
= DDBToDIB(hBitmap);
    ::SelectObject(hMemDc, hOldBitmap);
    ::DeleteObject(hBitmap);
    ::DeleteDC(hMemDc);
    ::ReleaseDC(hWnd, hWndDc);
    
return hDib;
}

BOOL SaveWindowToBMP(CHAR 
* pBMPName, HWND hWnd, RECT * pWndRect)
{
    HANDLE    hDib;
    ::ShowWindow(hWnd, SW_SHOW);
    ::BringWindowToTop(hWnd);
    ::UpdateWindow(hWnd);
    hDib 
= GetDIBFromWindow(hWnd, pWndRect);
    SaveDIBToBMP(hDib, pBMPName);
    GlobalFree(hDib);
    
return TRUE;
}

BOOL GetBitmapSize(HBITMAP hBitmap, DWORD 
* pdwBmInfoSize, DWORD * pdwDIBSize, int nBit)
{
    BITMAP                BM;
    
int                    nRetVal, nColors, nBitpPix;
    
if(hBitmap == NULL)
    {
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return FALSE;
    }
    nRetVal 
= GetObject(hBitmap, sizeof(BITMAP), (LPVOID)&BM);
    
if(nRetVal != sizeof(BITMAP))
    {
        Msgerr(
"GetObject");
        
return FALSE;
    }
    
if(nBit != 0)    nBitpPix    = nBit;
    
else            nBitpPix    = BM.bmBitsPixel;
    nColors 
= 1  <<  nBitpPix;
    
if(nBitpPix <= 8)
        
*pdwBmInfoSize = sizeof(BITMAPINFOHEADER) + nColors*sizeof(RGBQUAD);
    
else    //无调色板
        *pdwBmInfoSize = sizeof(BITMAPINFOHEADER);
    
*pdwDIBSize = *pdwBmInfoSize + ((BM.bmWidth * nBitpPix +31/ 32* 4 * BM.bmHeight;
    
return TRUE;
}

BOOL SaveHiconToICOFile(HICON hIcon, CHAR 
* pFileName, int nBit)
{
    ICONHEADER        IconHead;
    ICONDIRENTRY    IconDir;
    ICONINFO        IconInfo;
    HANDLE            hFile;
    VOID 
*            pColorDIB;
    VOID 
*            pMaskDIB;
    BITMAPINFO 
*    pColorInfo;
    BITMAPINFO 
*    phMaskInfo;
    DWORD    dwColorInfoSize, dwMaskInfoSize;
    DWORD    dwColorDIBSize,  dwMaskDIBSize;
    DWORD            dwWrite;
    BOOL            bRetVal;

    
if(hIcon == NULL || pFileName == NULL)
    {
        SetLastError(ERROR_INVALID_HANDLE);
        
return FALSE;
    }
    
if(nBit != 0 && nBit != 1 && nBit != 4 && nBit != 5 && 
        nBit 
!= 16 && nBit != 32)
    {
        SetLastError(ERROR_INVALID_HANDLE);
        
return FALSE;
    }
    hFile 
= CreateFileA(pFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL 
| FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    
if (hFile == INVALID_HANDLE_VALUE)
    {
        
return FALSE;
    }
    memset(
&IconHead, 0sizeof(IconHead));
    memset(
&IconDir, 0sizeof(IconDir));
    GetIconInfo(hIcon,  
&IconInfo);

    GetBitmapSize(IconInfo.hbmColor, 
&dwColorInfoSize, &dwColorDIBSize, nBit);
    GetBitmapSize(IconInfo.hbmColor, 
&dwMaskInfoSize,  &dwMaskDIBSize,  1);
    pColorInfo    
= (BITMAPINFO *)malloc(dwColorInfoSize);  
    phMaskInfo    
= (BITMAPINFO *)malloc(dwMaskInfoSize); 
    
if(pColorInfo == NULL || phMaskInfo == NULL)
    {
        ::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        
return NULL;
    }
    memset(pColorInfo, 
0, dwColorInfoSize);
    memset(phMaskInfo, 
0, dwMaskInfoSize);
    pColorDIB    
= DDBToDIB(IconInfo.hbmColor, NULL, pColorInfo, 0);
    pMaskDIB    
= DDBToDIB(IconInfo.hbmMask,  NULL, phMaskInfo, 1);    //单色蒙板

    IconHead.idReserved    
= 0;
    IconHead.idType        
= 1;
    IconHead.idCount    
= 1;        //一个图标
    IconDir.bWidth        = (BYTE)pColorInfo->bmiHeader.biWidth;
    IconDir.bHeight        
= (BYTE)pColorInfo->bmiHeader.biHeight;
    IconDir.bColorCount    
= pColorInfo->bmiHeader.biPlanes  *  pColorInfo->bmiHeader.biBitCount;
    IconDir.dwBytesInRes    
= dwColorDIBSize  +  dwMaskDIBSize - dwMaskInfoSize;
    IconDir.dwImageOffset    
= sizeof(IconHead)  +  sizeof(IconDir);
    bRetVal 
&= WriteFile(hFile, &IconHead, sizeof(IconHead), &dwWrite, NULL);
    bRetVal 
&= WriteFile(hFile, &IconDir,  sizeof(IconDir),  &dwWrite, NULL);
    pColorInfo
->bmiHeader.biHeight        *= 2;    //Color + Mask
    pColorInfo->bmiHeader.biSizeImage    += dwMaskDIBSize - dwMaskInfoSize;
    bRetVal 
&= WriteFile(hFile, pColorInfo, dwColorInfoSize, &dwWrite, NULL);
    bRetVal 
&= WriteFile(hFile, (BYTE *)pColorDIB + dwColorInfoSize, dwColorDIBSize - dwColorInfoSize, &dwWrite, NULL);
    bRetVal 
&= WriteFile(hFile, (BYTE *)pMaskDIB  + dwMaskInfoSize,  dwMaskDIBSize  - dwMaskInfoSize,  &dwWrite, NULL);
    
    
// Ben: WriteFile() do the correct thing, but return 0, so:
    DWORD nErr;
    nErr 
= GetLastError();
    bRetVal 
= (0 == nErr) ? TRUE:FALSE;

    free(pColorInfo);
    free(phMaskInfo);
    GlobalFree(pColorDIB);    
//for DDBToDIB
    GlobalFree(pMaskDIB);
    DeleteObject(IconInfo.hbmColor);
    DeleteObject(IconInfo.hbmMask);
    CloseHandle(hFile);
    
return  bRetVal;
}

DWORD DibMaskFill(HANDLE hDib, HANDLE hMaskDib, COLORREF Color)
{
    BITMAPINFO 
*    pColorInfo;
    BITMAPINFO 
*    phMaskInfo;
    pColorInfo 
= (BITMAPINFO *)hDib;
    phMaskInfo 
= (BITMAPINFO *)hMaskDib;
    
if(phMaskInfo->bmiHeader.biBitCount > 2)    //    蒙板 不是单色
    {
        
return 0;
    }
    
return 0;
}

HBITMAP GetHiconBitmap(HICON hIcon, COLORREF Color)
{
    ICONINFO    IconInfo;
    BITMAP        BM;
    HBITMAP        hBitmap, hBitmapOld1, hBitmapOld2;
    BOOL        bRetVal 
= TRUE;
    HDC        hmDC, hMemDc1, hMemDc2;
    hmDC    
= GetDC(NULL);
    hMemDc1    
= CreateCompatibleDC(hmDC);
    hMemDc2    
= CreateCompatibleDC(hmDC);
    
if(GetIconInfo(hIcon, &IconInfo) == FALSE)
    {
        Msgerr(
"GetIconInfo Error!");
        
return NULL;
    }
    GetObject(IconInfo.hbmColor, 
sizeof(BITMAP), &BM);
    hBitmap 
= CreateBitmap(BM.bmWidth, BM.bmHeight, BM.bmPlanes, BM.bmBitsPixel, NULL);
    hBitmapOld1 
= (HBITMAP)::SelectObject(hMemDc1, hBitmap);
    hBitmapOld2 
= (HBITMAP)::SelectObject(hMemDc2, IconInfo.hbmColor);
    FloodFill(hMemDc1, 
00, Color);
    bRetVal 
= MaskBlt(hMemDc1, 00, BM.bmWidth, BM.bmHeight, hMemDc2, 00, IconInfo.hbmMask, 000xCCAA0000);
    
if(bRetVal == FALSE)
    {
        Msgerr(
"MaskBlt Error");
        
return NULL;
    }
    ::SelectObject(hMemDc1, hBitmapOld1);
    ::SelectObject(hMemDc2, hBitmapOld2);
    DeleteObject(IconInfo.hbmColor);
    DeleteObject(IconInfo.hbmMask);
    DeleteDC(hMemDc1);
    DeleteDC(hMemDc2);
    ::ReleaseDC(NULL, hmDC);
    
return hBitmap;
}

#ifdef USEJPEGLIB

BOOL SaveBitmapToJPG(HBITMAP hBitMap, CHAR 
* pJPGName, int nQuality)
{
    HANDLE        hDib 
= NULL;
    HPALETTE    hPalette 
= NULL;
    BOOL        bRetVal;
    hDib 
= DDBToDIB(hBitMap, hPalette);
    
if(hDib == NULL)
    {
        
return FALSE;
    }
    bRetVal 
= JpegFromDib(hDib, nQuality, pJPGName);
    GlobalFree(hDib);
    
return bRetVal;
}

RGBQUAD QuadFromWord(WORD b16)
{
    BYTE bytVals[] 
=
    {
        
0,  162432,  40485664,
            
72808896104,112,120,128,
            
136,144,152,160,168,176,184,192,
            
200,208,216,224,232,240,248,255
    };
    WORD wR 
= b16;
    WORD wG 
= b16;
    WORD wB 
= b16;
    RGBQUAD rgb;
    wR 
<<= 1; wR >>= 11;
    wG 
<<= 6; wG >>= 11;
    wB 
<<= 11; wB >>= 11;
    rgb.rgbReserved 
= 0;
    rgb.rgbBlue     
= bytVals[wB];
    rgb.rgbGreen    
= bytVals[wG];
    rgb.rgbRed      
= bytVals[wR];
    
return rgb;
}

BOOL DibToSamps(HANDLE hDib, 
int nSampsPerRow, struct jpeg_compress_struct cinfo,
    JSAMPARRAY jsmpPixels)
{
    
//Sanity...
    if (hDib == NULL || nSampsPerRow <= 0
    { 
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return FALSE; 
    } 
    
int r=0, p=0, q=0, b=0, n=0
        nUnused
=0, nBytesWide=0, nUsed=0, nLastBits=0, nLastNibs=0, nCTEntries=0,
        nRow
=0, nByte=0, nPixel=0;
    BYTE bytCTEnt
=0;
    LPBITMAPINFOHEADER pbBmHdr
= (LPBITMAPINFOHEADER)hDib; //The bit count tells you the format of the bitmap: //Decide how many entries will be in the color table (if any) 
    switch (pbBmHdr->biBitCount)
    {
    
case 1:
        nCTEntries 
= 2;   //Monochrome
        break;
    
case 4:
        nCTEntries 
= 16;  //16-color
        break;
    
case 8:
        nCTEntries 
= 256//256-color
        break;
    
case 16:
    
case 24:
    
case 32:
        nCTEntries 
= 0;   //No color table needed
        break;
    
default:
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return FALSE; //Unsupported format
    }

    DWORD     dwCTab 
= (DWORD)pbBmHdr + pbBmHdr->biSize;
    LPRGBQUAD pCTab  
= (LPRGBQUAD)(dwCTab);
    LPSTR     lpBits 
= (LPSTR)pbBmHdr +
        (WORD)pbBmHdr
->biSize +    (WORD)(nCTEntries * sizeof(RGBQUAD));

    
//Different formats for the image bits
    LPBYTE   lpPixels = (LPBYTE)  lpBits;
    RGBQUAD
* pRgbQs   = (RGBQUAD*)lpBits;
    WORD
*    wPixels  = (WORD*)   lpBits;

    
//Set up the jsamps according to the bitmap's format.
    
//Note that rows are processed bottom to top, because
    
//that's how bitmaps are created.
    switch (pbBmHdr->biBitCount)
    {
    
case 1:
        nUsed      
= (pbBmHdr->biWidth + 7/ 8;
        nUnused    
= (((nUsed + 3/ 4* 4- nUsed;
        nBytesWide 
= nUsed + nUnused;
        nLastBits  
= 8 - ((nUsed * 8- pbBmHdr->biWidth);

        
for (r=0; r < pbBmHdr->biHeight; r++)
        {
            
for (p=0, q=0; p < nUsed; p++
            { 
                nRow
=(pbBmHdr->biHeight-r-1* nBytesWide;
                nByte 
=  nRow + p;
                
int nBUsed = (p < (nUsed >> 1) ) ? 8 : nLastBits;
                
//                                        ^^        Not sure about this symbol Might be problem               
                for(b=0; b < nBUsed;b++
                { 
                    bytCTEnt 
= lpPixels[nByte] << b; 
                    bytCTEnt 
= bytCTEnt >> 7;

                    jsmpPixels[r][q
+0= pCTab[bytCTEnt].rgbRed;
                    jsmpPixels[r][q
+1= pCTab[bytCTEnt].rgbGreen;
                    jsmpPixels[r][q
+2= pCTab[bytCTEnt].rgbBlue;

                    q 
+= 3;
                }
            }
        }
        
break;

    
case 4:
        nUsed      
= (pbBmHdr->biWidth + 1/ 2;
        nUnused    
= (((nUsed + 3/ 4* 4- nUsed;
        nBytesWide 
= nUsed + nUnused;
        nLastNibs  
= 2 - ((nUsed * 2- pbBmHdr->biWidth);

        
for (r=0; r < pbBmHdr->biHeight;r++)
        {
            
for (p=0,q=0; p < nUsed;p++
            { 
                nRow
=(pbBmHdr->biHeight-r-1* nBytesWide;
                nByte 
= nRow + p;

                
int nNibbles = (p  >> (4- (n * 4)) );
                jsmpPixels[r][q
+0= pCTab[bytCTEnt].rgbRed;
                jsmpPixels[r][q
+1= pCTab[bytCTEnt].rgbGreen;
                jsmpPixels[r][q
+2= pCTab[bytCTEnt].rgbBlue;
                q 
+= 3;
            }
        }
        
break;

    
default:
    
case 8//Each byte is a pointer to a pixel color
        nUnused = (((pbBmHdr->biWidth + 3/ 4* 4-
            pbBmHdr
->biWidth;

        
for (r=0;r < pbBmHdr->biHeight; r++)
        {
            
for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3)
            {
                nRow   
= (pbBmHdr->biHeight-r-1* (pbBmHdr->biWidth + nUnused);
                nPixel 
=  nRow + p;

                jsmpPixels[r][q
+0= pCTab[lpPixels[nPixel]].rgbRed;
                jsmpPixels[r][q
+1= pCTab[lpPixels[nPixel]].rgbGreen;
                jsmpPixels[r][q
+2= pCTab[lpPixels[nPixel]].rgbBlue;
            }
        }
        
break;

    
case 16//Hi-color (16 bits per pixel)
        for (r=0;r < pbBmHdr->biHeight; r++)
        {
            
for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3)
            {
                nRow    
= (pbBmHdr->biHeight-r-1* pbBmHdr->biWidth;
                nPixel  
= nRow + p;

                RGBQUAD quad 
= QuadFromWord(wPixels[nPixel]);

                jsmpPixels[r][q
+0= quad.rgbRed;
                jsmpPixels[r][q
+1= quad.rgbGreen;
                jsmpPixels[r][q
+2= quad.rgbBlue;
            }
        }
        
break;

    
case 24:
        nBytesWide 
=  (pbBmHdr->biWidth*3);
        nUnused    
=  (((nBytesWide + 3/ 4* 4-
            nBytesWide;
        nBytesWide 
+= nUnused;

        
for (r=0; r < pbBmHdr->biHeight; r++)
        {
            
for (p=0,q=0;p < (nBytesWide-nUnused); p+=3,q+=3)
            { 
                nRow 
= (pbBmHdr->biHeight-r-1* nBytesWide;
                nPixel  
= nRow + p;

                jsmpPixels[r][q
+0= lpPixels[nPixel+2]; //Red
                jsmpPixels[r][q+1= lpPixels[nPixel+1]; //Green
                jsmpPixels[r][q+2= lpPixels[nPixel+0]; //Blue
            }
        }
        
break;

    
case 32:
        
for (r=0; r < pbBmHdr->biHeight; r++)
        {
            
for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3)
            {
                nRow    
= (pbBmHdr->biHeight-r-1*
                    pbBmHdr
->biWidth;
                nPixel  
= nRow + p;

                jsmpPixels[r][q
+0= pRgbQs[nPixel].rgbRed;
                jsmpPixels[r][q
+1= pRgbQs[nPixel].rgbGreen;
                jsmpPixels[r][q
+2= pRgbQs[nPixel].rgbBlue;
            }
        }
        
break;
    }   
//end switch
    return TRUE;
}

BOOL JpegFromDib(HANDLE hDib, 
int nQuality, CHAR * pJPGName)
{
    BOOL    bRetVal;
    
int        nError;
    
//Basic sanity checks...
    if (nQuality < 0 || nQuality > 100 || hDib   == NULL)
    {
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return FALSE;
    }
    
byte *buf2 = 0;
    
//Use libjpeg functions to write scanlines to disk in JPEG format
    jpeg_compress_struct * pcinfo = (jpeg_compress_struct *)malloc(sizeof(jpeg_compress_struct) * 4);
    memset(pcinfo, 
0sizeof(jpeg_compress_struct) * 4);    //WARNING    jpeg_start_compress OVER
    struct jpeg_error_mgr       jerr;

    FILE
*      pOutFile;     //Target file 
    int        nSampsPerRow; //Physical row width in image buffer 
    JSAMPARRAY jsmpArray;    //Pixel RGB buffer for JPEG file
    pcinfo->err = jpeg_std_error(&jerr); //Use default error handling (ugly!)

    jpeg_create_compress(pcinfo);

    pOutFile 
= fopen(pJPGName, "wb");
    
if (pOutFile == NULL)
    {
        nError 
= ::GetLastError();
        jpeg_destroy_compress(pcinfo);
        ::SetLastError(nError);
        free(pcinfo);
        
return FALSE;
    }

    jpeg_stdio_dest(pcinfo, pOutFile);

    LPBITMAPINFOHEADER lpbi 
= (LPBITMAPINFOHEADER)hDib;

    pcinfo
->image_width      = lpbi->biWidth;  //Image width and height, in pixels 
    pcinfo->image_height     = lpbi->biHeight;
    pcinfo
->input_components = 3;              //Color components per pixel
    
//(RGB_PIXELSIZE - see jmorecfg.h)
    pcinfo->in_color_space   = JCS_RGB;          //Colorspace of input image

    jpeg_set_defaults(pcinfo);
    jpeg_set_quality(pcinfo, nQuality, TRUE);    
//Limit to baseline-JPEG values
    jpeg_start_compress(pcinfo, TRUE);

    
//JSAMPLEs per row in output buffer
    nSampsPerRow = pcinfo->image_width * pcinfo->input_components; 

    
//Allocate array of pixel RGB values
    jsmpArray = (*pcinfo->mem->alloc_sarray)
        ((j_common_ptr) pcinfo,    JPOOL_IMAGE, nSampsPerRow, pcinfo
->image_height);
    bRetVal 
= DibToSamps(hDib, nSampsPerRow, *pcinfo, jsmpArray);
    
if(bRetVal == FALSE)
    {
        nError 
= ::GetLastError();
        jpeg_finish_compress(pcinfo); 
//Always finish
        fclose(pOutFile);
        jpeg_destroy_compress(pcinfo); 
//Free resources
        free(pcinfo);
        ::SetLastError(nError);
        
return FALSE;
    }
    
//Write the array of scan lines to the JPEG file
    jpeg_write_scanlines(pcinfo, jsmpArray, pcinfo->image_height);
    jpeg_finish_compress(pcinfo); 
//Always finish
    fclose(pOutFile);
    jpeg_destroy_compress(pcinfo); 
//Free resources
    free(pcinfo);
    
return TRUE;
}

#endif

/*
//  Bmp转换为Ico格式,  nBit为色彩位数,  支持位数如下:
//  0,  1,  4,  8,  16,  24,  32
//-------------------------
void  Bmp2Ico(String  strBmpFileName,  int  nBit)
{
    int  nIconWidth    =  GetSystemMetrics(SM_CXICON);
    int  nIconHeight  =  GetSystemMetrics(SM_CYICON);;
    Graphics::TBitmap  *MyBmp  =  new  Graphics::TBitmap();
    MyBmp->LoadFromFile(strBmpFileName);
    Graphics::TBitmap  *AndMask  =  new  Graphics::TBitmap();
    AndMask->Width    =  nIconWidth;
    AndMask->Height  =  nIconHeight;
    AndMask->Canvas->Brush->Color  =  clBlack;
    AndMask->Canvas->Rectangle(0,  0,  nIconWidth,  nIconHeight);
    Graphics::TBitmap  *XorMask  =  new  Graphics::TBitmap();
    XorMask->Width    =  nIconWidth;
    XorMask->Height  =  nIconHeight;
    StretchBlt(XorMask->Canvas->Handle,  0,  0,  nIconWidth,  nIconHeight,
        MyBmp->Canvas->Handle,  0,  0,  MyBmp->Width,  MyBmp->Height,  SRCCOPY);
    TIcon  *pIcon  =  new  TIcon();
    TIconInfo  IconInfo;
    IconInfo.fIcon  =  true;
    IconInfo.xHotspot  =  0;
    IconInfo.yHotspot  =  0;
    IconInfo.hbmMask    =  AndMask->Handle;
    IconInfo.hbmColor  =  XorMask->Handle;
    pIcon->Handle  =  CreateIconIndirect(&IconInfo);
    delete  AndMask;
    delete  XorMask;
    delete  MyBmp;
    String  strIcoFileName  =  ChangeFileExt(strBmpFileName,  ".ico");
    SaveIcon(pIcon->Handle,  strIcoFileName.c_str(),  nBit);
    delete  pIcon;
}
*/
 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 此苹果已丢失并被抹掉怎么办 苹果手机显示已丢失并被抹掉怎么办 手机在保修期内坏了售后拖延怎么办 微信图片在电脑上打印不清楚怎么办 遇到职业搞坏淘宝店铺的买家怎么办 眼破裂伤无光感半个月怎么办 出了虫的豆豆熬稀饭喝了怎么办? 果汁阳台月季叶子掉光了怎么办 近看好看远看难看该怎么办 衣服褶皱没有熨斗的情况下怎么办 裤子磨得发亮怎么办也没有电熨斗 老是在灯箱拍照对眼睛不好怎么办 电信光纤宽带账号密码忘记了怎么办 遇到尴尬的事情自己缓不过来怎么办 注销微信账号显示非法请求怎么办 微信备份以前的被覆盖了怎么办 之前微信号被新微信号覆盖了怎么办 微信发出的消息变成绿色怎么办 收了客户的资金被骗走了怎么办 淘宝退回去的衣服店家不接收怎么办 淘宝同款衣服价格相差很大该怎么办 淘宝买的衣服退回去了不退钱怎么办 淘宝客人退回的衣服有口红印怎么办 淘宝拍产品照片被投诉著作权怎么办 员工总在节假日忙的时候请假怎么办 买东西商家少给了货应该怎么办 买家退回的衣服有污渍卖家该怎么办 商家说衣服有污渍不退怎么办 退回商家换货不给寄应怎么办 毕业照跟拍摄影师拍砸了怎么办 韵达快递寄快递快递单号丢了怎么办 韵达快递把我的户口本弄丢了怎么办 淘宝卖家发货与实际货物不符怎么办 寄出去的快递不知道物流单号怎么办 淘宝买家所需要的货物填错怎么办 淘宝卖家顾客拒绝签收货要怎么办 闲鱼买家申请退货退款不发货怎么办 在闲鱼买东西买家恶意退货怎么办 淘宝卖家给的退货地址是国外怎么办 淘宝顾客下单了一件代发怎么办 闲鱼上卖东西快递单号填错了怎么办