我用vb编了一个屏幕取图的程序,但要求通过局域网进行传送.考虑到传送过程中图象数据较大,影响传输速度.所以需要将图象进行压缩后在传送.请问各位大侠如何进行图象压缩及解压缩.小弟万分感谢.

解决方案 »

  1.   

    将屏幕取的图转为jpg的就可以了(程序很长,我分开回复)
    ///////////////////////////////////////////////////////////////Example of use:
    /////////////////////////////////////////////////////////////void MakeJpeg(){
        CBitmap  cBitmap;    BITMAP   bm;    CString  csMsg = "";
        cBitmap.LoadBitmap(IDB_TEST);    cBitmap.GetBitmap(&bm);
        HANDLE  hDib = DDBToDIB((HBITMAP)cBitmap,
                                 BI_RGB,
                                 NULL);  //Use default palette
        //Turn DIB into JPEG file    if (hDib != NULL)    {
            if (!JpegFromDib(hDib,                         100,   //Quality setting
                             "test.jpg",                         &csMsg))        {
                AfxMessageBox(csMsg);        }        else
                AfxMessageBox("test.jpg created");        ::GlobalFree(hDib);    }
        else        AfxMessageBox("Failed to load IDB_TEST");}
    ////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////Header file code
    ////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////
    //In the relevant header file (up near the top):#include "jpeglib.h"
    BOOL JpegFromDib(HANDLE     hDib,     //Handle to DIB
                     int        nQuality, //JPEG quality (0-100)
                     CString    csJpeg,   //Pathname to target jpeg file
                     CString*   pcsMsg);  //Error msg to return
    BOOL BuildSamps(HANDLE                      hDib,
                    int                         nSampsPerRow,
                    struct jpeg_compress_struct cinfo,
                    JSAMPARRAY                  jsmpArray,
                    CString*                    pcsMsg);
    RGBQUAD QuadFromWord(WORD b16);
    ////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////Source file code
    ////////////////////////////////////////////////////////////
      

  2.   

    ////////////////////////////////////////////////////////////extern "C"{
    #include "jpeglib.h"}         #include struct ima_error_mgr{
      struct  jpeg_error_mgr pub; //"public" fields
      jmp_buf setjmp_buffer;   //for return to caller};
    ////////////////////////////////////////////////////////////////////////////
    //This function takes the contents of a DIB//and turns it into a JPEG file.//
    //The DIB may be monochrome, 16-color, 256-color, or 24-bit color.//
    //Any functions or data items beginning with "jpeg_" belong to jpeg.lib,
    //and are not included here.//
    //The function assumes 3 color components per pixel.
    /////////////////////////////////////////////////////////////////////////////
    BOOL JpegFromDib(HANDLE     hDib,     //Handle to DIB
                     int        nQuality, //JPEG quality (0-100)
                     CString    csJpeg,   //Pathname to jpeg file
                     CString*   pcsMsg)   //Error msg to return{
        //Basic sanity checks...    if (nQuality < 0 || nQuality > 100 ||
            hDib   == NULL ||        pcsMsg == NULL ||        csJpeg == "")    {
            if (pcsMsg != NULL)            *pcsMsg = "Invalid input data";
            return FALSE;    }    *pcsMsg = "";
        LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)hDib;    byte *buf2 = 0;
        //Use libjpeg functions to write scanlines to disk in JPEG format
        struct jpeg_compress_struct cinfo;    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
        cinfo.err = jpeg_std_error(&jerr); //Use default error handling (ugly!)
        jpeg_create_compress(&cinfo);
        if ((pOutFile = fopen(csJpeg, "wb")) == NULL)    {
            *pcsMsg = "Cannot open "; *pcsMsg += csJpeg;
            jpeg_destroy_compress(&cinfo);        return FALSE;    }
        jpeg_stdio_dest(&cinfo, pOutFile);
        cinfo.image_width      = lpbi->biWidth;  //Image width and height, in pixels 
        cinfo.image_height     = lpbi->biHeight;
        cinfo.input_components = 3;              //Color components per pixel
                                                 //(RGB_PIXELSIZE - see jmorecfg.h)
        cinfo.in_color_space   = JCS_RGB;       //Colorspace of input image
        jpeg_set_defaults(&cinfo);    jpeg_set_quality(&cinfo,
                         nQuality, //Quality: 0-100 scale
                         TRUE);    //Limit to baseline-JPEG values
        jpeg_start_compress(&cinfo, TRUE);    //JSAMPLEs per row in output buffer
        nSampsPerRow = cinfo.image_width * cinfo.input_components; 
        //Allocate array of pixel RGB values
        jsmpArray = (*cinfo.mem->alloc_sarray)
                    ((j_common_ptr) &cinfo,                 JPOOL_IMAGE,
                     nSampsPerRow,                 cinfo.image_height);
        if (DibToSamps(hDib,                   nSampsPerRow,
                       cinfo,                   jsmpArray,
                       pcsMsg))    {
            //Write the array of scan lines to the JPEG file
            (void)jpeg_write_scanlines(&cinfo,
                                       jsmpArray,
                                       cinfo.image_height);    }
        jpeg_finish_compress(&cinfo); //Always finish    fclose(pOutFile);
        jpeg_destroy_compress(&cinfo); //Free resources    if (*pcsMsg != "")
            return FALSE;    else        return TRUE;}
      

  3.   

    ////////////////////////////////////////////////////////////////
    //This function fills a jsmpArray with the RGB values//for the CBitmap.//
    //It has been improved to handle all legal bitmap formats.//
    //A jsmpArray is a big array of RGB values, 3 bytes per value.//
    //Note that rows of pixels are processed bottom to top:
    //The data in the jsamp array must be arranged top to bottom.
    ////////////////////////////////////////////////////////////////
    BOOL DibToSamps(HANDLE                      hDib,
                    int                         nSampsPerRow,
                    struct jpeg_compress_struct cinfo,
                    JSAMPARRAY                  jsmpPixels,
                    CString*                    pcsMsg){   //Sanity...
       if (hDib == NULL    ||     nSampsPerRow <= 0 || pcsMsg == NULL)    { 
         if (pcsMsg !=NULL)         *pcsMsg="Invalid input data"; 
         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:         *pcsMsg = "Invalid bitmap bit count";
             return FALSE; //Unsupported format   }
       //Point to the color table and pixels
       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; 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 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 switchreturn TRUE;} 
    //////////////////////////////////////////This function turns a 16-bit pixel
    //into an RGBQUAD value.////////////////////////////////////////
    RGBQUAD QuadFromWord(WORD b16){   BYTE bytVals[] =   {
         0,  16, 24, 32,  40, 48, 56, 64,     72, 80, 88, 96, 104,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;   wR <<= 1; wR >>= 11;
       wG <<= 6; wG >>= 11;   wB <<= 11; wB >>= 11;   RGBQUAD rgb;
       rgb.rgbReserved = 0;   rgb.rgbBlue     = bytVals[wB];
       rgb.rgbGreen    = bytVals[wG];   rgb.rgbRed      = bytVals[wR];   return rgb;
    }