你想怎么显示,象ACDSEE用DirectX? or GDI?

解决方案 »

  1.   

    在WINDOWS中系统不支持许多的格式直接显示,大多数的图形格式都需要转换为BMP格式处理,在WINDOW98/2000中增加了对JPG和PNG格式的直接支持可以直接用StretchDIBits操作。
      

  2.   

    恐怕大多数格式是先转换为DIB格式吧。
      

  3.   

    我是指在窗口中显示bmp,gif,jpg格式的图形文件,且截取图像的某一指定范围,保存为bmp格式的图形文件.
      

  4.   

    //加载图象
    LoadPictureFromFile(HDC hdc, LPCTSTR szFile, CBitmap *pBitmap, CSize &mSize)
    {
    // open file
    HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    _ASSERTE(INVALID_HANDLE_VALUE != hFile); // get file size
    DWORD dwFileSize = GetFileSize(hFile, NULL);
    _ASSERTE(-1 != dwFileSize); LPVOID pvData = NULL;
    // alloc memory based on file size
    HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
    _ASSERTE(NULL != hGlobal); pvData = GlobalLock(hGlobal);
    _ASSERTE(NULL != pvData); DWORD dwBytesRead = 0;
    // read file and store in global memory
    BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
    _ASSERTE(FALSE != bRead);
    GlobalUnlock(hGlobal);
    CloseHandle(hFile); LPSTREAM pstm = NULL;
    // create IStream* from global memory
    HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
    _ASSERTE(SUCCEEDED(hr) && pstm); // Create IPicture from image file
    LPPICTURE gpPicture; hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);

    _ASSERTE(SUCCEEDED(hr) && gpPicture);
    pstm->Release(); OLE_HANDLE m_picHandle;
    /*
    long hmWidth, hmHeight;
    gpPicture->get_Width(&hmWidth);
    gpPicture->get_Height(&hmHeight);
    int nWidth = MulDiv(hmWidth, GetDeviceCaps(hdc, LOGPIXELSX), HIMETRIC_INCH);
    int nHeight = MulDiv(hmHeight, GetDeviceCaps(hdc, LOGPIXELSY), HIMETRIC_INCH);
    */
    gpPicture->get_Handle(&m_picHandle);
    pBitmap->DeleteObject();
    pBitmap->Attach((HGDIOBJ) m_picHandle); BITMAP bm;
    GetObject(pBitmap->m_hObject, sizeof(bm), &bm);
    mSize.cx = bm.bmWidth; //nWidth;
    mSize.cy = bm.bmHeight; //nHeight;
    }//截取图象
    void CopyBitmap(CDC *dc, CBitmap &mRes, const CBitmap &hbmp, RECT r)
    {
    if(!hbmp.m_hObject) return;
    int w = r.right - r.left,
    h = r.bottom - r.top; CDC memdc, hDC;

    mRes.CreateCompatibleBitmap(dc, w, h); hDC.CreateCompatibleDC(dc);
    hDC.SelectObject((HBITMAP) mRes); memdc.CreateCompatibleDC(dc);
    memdc.SelectObject(hbmp); hDC.StretchBlt(0, 0, w, h, &memdc, r.left, r.top, w, h, SRCCOPY); 
    hDC.DeleteDC();
    memdc.DeleteDC();
    }//DDB转变为DIB,准备保存// DDBToDIB - Creates a DIB from a DDB
    // bitmap - Device dependent bitmap
    // dwCompression - Type of compression - see BITMAPINFOHEADER
    // pPal - Logical palette
    HANDLE DDBToDIB(CBitmap &bitmap, DWORD dwCompression, CPalette *pPal)
    {
    BITMAP bm;
    BITMAPINFOHEADER bi;
    LPBITMAPINFOHEADER  lpbi;
    DWORD dwLen;
    HANDLE hDIB;
    HANDLE handle;
    HDC  hDC;
    HPALETTE hPal;
    ASSERT( bitmap.GetSafeHandle() ); // The function has no arg for bitfields
    if( dwCompression == BI_BITFIELDS )
    return NULL; // If a palette has not been supplied use defaul palette
    hPal=NULL;
    if(pPal!=NULL)
    {
    hPal = (HPALETTE) pPal->GetSafeHandle();
    }
    if (hPal==NULL)
    hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); // Get bitmap information
    bitmap.GetObject(sizeof(bm),(LPSTR)&bm); // Initialize the bitmapinfoheader
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bm.bmWidth;
    bi.biHeight  = bm.bmHeight;
    bi.biPlanes  = 1;
    bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
    bi.biCompression = dwCompression;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0; // Compute the size of the  infoheader and the color table
    int nColors = (1 << bi.biBitCount); if( nColors > 256 ) 
    nColors = 0;
    dwLen  = bi.biSize + nColors * sizeof(RGBQUAD); // We need a device context to get the DIB from
    hDC = GetDC(NULL);
    hPal = SelectPalette(hDC,hPal,FALSE);
    RealizePalette(hDC); // Allocate enough memory to hold bitmapinfoheader and color table
    hDIB = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDIB){
    SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);
    return NULL;
    } lpbi = (LPBITMAPINFOHEADER)hDIB; *lpbi = bi; // Call GetDIBits with a NULL lpBits param, so the device driver 
    // will calculate the biSizeImage field 
    GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
    (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS); bi = *lpbi; // If the driver did not fill in the biSizeImage field, then compute it
    // Each scan line of the image is aligned on a DWORD (32bit) boundary
    if (bi.biSizeImage == 0){
    bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) 
    * bi.biHeight; // If a compression scheme is used the result may infact be larger
    // Increase the size to account for this.
    if (dwCompression != BI_RGB)
    bi.biSizeImage = (bi.biSizeImage * 3) / 2;
    } // Realloc the buffer so that it can hold all the bits
    dwLen += bi.biSizeImage;
    if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
    hDIB = handle;
    else{
    GlobalFree(hDIB); // Reselect the original palette
    SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);
    return NULL;
    } // Get the bitmap bits
    lpbi = (LPBITMAPINFOHEADER)hDIB; // FINALLY get the DIB
    BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
    0L, // Start scan line
    (DWORD)bi.biHeight, // # of scan lines
    (LPBYTE)lpbi  // address for bitmap bits
    + (bi.biSize + nColors * sizeof(RGBQUAD)),
    (LPBITMAPINFO)lpbi, // address of bitmapinfo
    (DWORD)DIB_RGB_COLORS); // Use RGB for color table if( !bGotBits )
    {
    GlobalFree(hDIB);

    SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);
    return NULL;
    } SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);
    return hDIB;
    }//保存DIB为位图文件
    int SaveBmp(HANDLE hDib, LPSTR filename)
    {
    /*
    BITMAPFILEHEADER bfh;
    BITMAPINFOHEADER *lpbi=(BITMAPINFOHEADER*)hDib; bfh.bfType=0x4D42; //BM
    bfh.bfSize=sizeof(bfh)+GlobalSize(hData);
    bfh.bfReserved1=bfh.bfReserved2=0;
    int colors=1<lpbi->biBitCount;
    if(colors>256) colors=0;
    bfh.bfOffBits=sizeof(bfh)+lpbi->biSize+colors*sizeof(RGBQUAD);  HANDLE hFile=CreateFile(filename,GENERIC_WRITE
    ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,NULL);
    if(hFile)
    {
    DWORD write;
    WriteFile(hFile,&bfh,sizeof(bfh),&write,NULL); 
    WriteFile(hFile,lpbi,GlobalSize(hData),&write,NULL);
    int i=sizeof(hData);
    CloseHandle(hFile);
    return true;
    }
    return false; 
    */
    CFile file;
    if(!file.Open(filename,CFile::modeCreate|CFile::modeWrite))
    return FALSE; BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
    LPBITMAPINFOHEADER lpBI;   // Pointer to DIB info structure
    DWORD dwDIBSize; if (hDib == NULL)
    {
    file.Close();
    return FALSE;
    } /*
     * Get a pointer to the DIB memory, the first of which contains
     * a BITMAPINFO structure
     */
    lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
    if (lpBI == NULL)
    {
    file.Close();
    return FALSE;
    } if (!((*(LPDWORD)(lpBI)) == sizeof(BITMAPINFOHEADER)))
    {
    ::GlobalUnlock((HGLOBAL) hDib);
    file.Close();
    return FALSE;       // It's an other-style DIB (save not supported)
    } /*
     * Fill in the fields of the file header
     */ /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
    bmfHdr.bfType = ((WORD) ('M' << 8) | 'B');  // "BM" // Calculating the size of the DIB is a bit tricky (if we want to
    // do it right).  The easiest way to do this is to call GlobalSize()
    // on our global handle, but since the size of our global memory may have
    // been padded a few bytes, we may end up writing out a few too
    // many bytes to the file (which may cause problems with some apps).
    //
    // So, instead let's calculate the size manually (if we can)
    //
    // First, find size of header plus size of color table.  Since the
    // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains
    // the size of the structure, let's use this. dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI);  // Partial Calculation // Now calculate the size of the image if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
    {
    // It's an RLE bitmap, we can't calculate size, so trust the
    // biSizeImage field dwDIBSize += lpBI->biSizeImage;
    }
    else
    {
    DWORD dwBmBitsSize;  // Size of Bitmap Bits only // It's not RLE, so size is Width (DWORD aligned) * Height dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight; dwDIBSize += dwBmBitsSize; // Now, since we have calculated the correct size, why don't we
    // fill in the biSizeImage field (this will fix any .BMP files which
    // have this field incorrect). lpBI->biSizeImage = dwBmBitsSize;
    }
    // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER) bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
    bmfHdr.bfReserved1 = 0;
    bmfHdr.bfReserved2 = 0; /*
     * Now, calculate the offset the actual bitmap bits will be in
     * the file -- It's the Bitmap file header plus the DIB header,
     * plus the size of the color table.
     */
    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
      + PaletteSize((LPSTR)lpBI);
    TRY
    {
    // Write the file header
    file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
    //
    // Write the DIB header and the bits
    //
    file.WriteHuge(lpBI, dwDIBSize);
    }
    CATCH (CFileException, e)
    {
    ::GlobalUnlock((HGLOBAL) hDib);
    THROW_LAST();
    }
    END_CATCH ::GlobalUnlock((HGLOBAL) hDib);
    file.Close();
    return TRUE;
    }简直累死了,行不行啊??