我现在在做个小控件,想实现图形得局部放大得功能。绘制好给定点所练成得图像后,当鼠标点击图像得某个部位就能显示该局部得放大图形。哪位大侠能给点思路!谢谢!

解决方案 »

  1.   

    标题     打印位图(上)    bluebohe(原作)  
      
    关键字     打印 位图 
      
           关于位图的打印,很多人对此很困惑,在这方面产生的问题也很多,主要包括以下几点。       1:打印的图片太小;       2:根本打印不出来位图       3:打印预览可见、但打印不出来;       产生这些问题的根本原因,在于对位图的理解不够深刻。       一个CBitmap对象,可能是DDB位图(设备相关位图),或者DIB位图(设备无关位图),其中,一个设备兼容的内存DC中,只能选择该设备兼容的DDB位图或者单色的位图。注意,位图只能被选择进入到设备兼容的内存DC中,并不能选择进入到真实的dc中,这就是有时候根本打印不出来图片的原因。       至于打印图片太小的问题,主要是因为衡量位图大小的单位是横向和纵向的像素数,而不是确切的长度,所以如果把一个图片映射到屏幕上,会出现一个比较大的图像,但是打印机的分辨率比屏幕高很多(屏幕一般是96dpi,而打印机最少一般也有300dpi),如果把位图不缩放地映射到打印机上,则必然要小很多。解决该类问题的方法是使用StretchBlt拉伸显示图像。       另外LoadImage函数中使用LR_CREATEDIBSECTION选项产生的DIB位图可以被选择进入任何设备兼容的内存DC中。因此可以使用LoadImage函数加载一个位图文件或者资源,直接把位图通过StretchBlt打印出来。下面是把一个位图文件进行打印的相关代码:/*//打印或者在屏幕左上角上画位图文件//pDC 打印机或者屏幕dc指针iLogPixelXiLogPixelY屏幕DC的GetDeviceCaps(LOGPIXELSX)值,其中iLogPixelX=DC.GetDeviceCaps(LOGPIXELSX);iLogPixelY=DC.GetDeviceCaps(LOGPIXELSY);const char *strFileName BMP图片文件名称*/void DrawBMP(CDC* pDC,int iLogPixelX,int iLogPixelY,const char *strFileName){         CDC          MemDC; // 内存设备环境指针,在视的整个存在过程都将存在         CBitmap         Bitmap,*pOldBmp;                CRect                Source, Dest; // 记录源位图尺寸和最终显示尺寸         BITMAP         bm;         if(MemDC.GetSafeHdc() == NULL)         {                  HBITMAP hbitmap=(HBITMAP)LoadImage(0,strFileName,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE);                  Bitmap.Attach(hbitmap);                  MemDC.CreateCompatibleDC(pDC);                  Bitmap.GetObject(sizeof(bm),&bm);                  pOldBmp=MemDC.SelectObject(&Bitmap);                  Source.top=0;                  Source.left=0;                  Source.right= bm.bmWidth;                  Source.bottom = bm.bmHeight;                   Dest = Source;         }         pDC->DPtoLP(&Dest);         if(pDC->IsPrinting())         {                  Dest.left=(int)(Dest.left*((double)pDC->GetDeviceCaps(LOGPIXELSX))/iLogPixelX);                  Dest.right=(int)(Dest.right*((double)pDC->GetDeviceCaps(LOGPIXELSX))/iLogPixelX);                  Dest.top=(int)(Dest.top*((double)pDC->GetDeviceCaps(LOGPIXELSY))/iLogPixelY);                  Dest.bottom=(int)(Dest.bottom*((double)pDC->GetDeviceCaps(LOGPIXELSY))/iLogPixelY);         }         pDC->StretchBlt(Dest.left, Dest.top, Dest.right, Dest.bottom,                  &MemDC, Source.left, Source.top, Source.right,Source.bottom, SRCCOPY);         MemDC.SelectObject(pOldBmp);         Bitmap.DeleteObject();         MemDC.DeleteDC();         return;}       但是对于显示设备兼容的DDB位图的打印则不是那么简单,比如屏幕截图,这种位图不能选择进入打印设备兼容的内存DC中,对于这种问题的处理,一般是通过转化成DIB位图,然后使用StretchDIBits函数把位图显示在DC上,下面是一个可以打印任何位图的函数代码。
     
      

  2.   

    标题     打印位图(下)    bluebohe(原作)  
      
    关键字     打印 位图 
      /*
    HDC hDC,                  打印机dcHBITMAP hBmp,         待打印位图int iX,                          位图的左上角点x坐标int iY,                           位图的左上角点y坐标double dScaleX,         打印机分辨率和屏幕分辨率x方向的比值,在没有指定位图显示高度和宽度的时候用的上double dScaleY,         打印机分辨率和屏幕分辨率y方向的比值,在没有指定位图显示高度和宽度的时候用的上int iWidth=0,         位图的显示宽度int iLength=0         位图的显示高度*/void Draw(HDC hDC,HBITMAP hBmp,int iX,int iY,double dScaleX=1.0,double dScaleY=1.0,int iWidth=0,int iLength=0){         HPALETTE hPal;         BITMAP                     bm;         BITMAPINFOHEADER         bi;         LPBITMAPINFOHEADER          lpbi;         DWORD                      dwLen;         HANDLE                     hDIB;         HANDLE                     handle;         HDC                            hDC1;         if(GetDeviceCaps(hDC,RASTERCAPS) & RC_PALETTE )         {                   UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);                  LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];                  pLP->palVersion = 0x300;                  pLP->palNumEntries =GetSystemPaletteEntries( hDC, 0, 255, pLP->palPalEntry );                  hPal=CreatePalette(pLP );                   delete[] pLP;         }         if (hPal==NULL)         hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);         ::GetObject(hBmp,sizeof(bm),(LPSTR)&bm);         bi.biSize             = sizeof(BITMAPINFOHEADER);         bi.biWidth                   = bm.bmWidth;         bi.biHeight                    = bm.bmHeight;         bi.biPlanes                    = 1;         bi.biBitCount                 = bm.bmPlanes * bm.bmBitsPixel;         bi.biCompression         = BI_RGB;         bi.biSizeImage              = 0;         bi.biXPelsPerMeter       = 0;         bi.biYPelsPerMeter       = 0;         bi.biClrUsed                   = 0;         bi.biClrImportant = 0;         int nColors = (1 << bi.biBitCount);         if( nColors > 256 )                  nColors = 0;         dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);         hDC1 = ::GetDC(NULL);         hPal = SelectPalette(hDC1,hPal,FALSE);         RealizePalette(hDC1);         hDIB = GlobalAlloc(GMEM_FIXED,dwLen);         if (!hDIB)         {                  SelectPalette(hDC1,hPal,FALSE);                  ::ReleaseDC(NULL,hDC1);                  DeleteObject(hPal);                   return ;         }         lpbi = (LPBITMAPINFOHEADER)hDIB;         *lpbi = bi;         ::GetDIBits(hDC1, hBmp, 0L, (DWORD)bi.biHeight,                  (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);         bi = *lpbi;         if (bi.biSizeImage == 0)                  bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)* bi.biHeight;         dwLen += bi.biSizeImage;         if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))                   hDIB = handle;         else         {                  GlobalFree(hDIB);                  SelectPalette(hDC1,hPal,FALSE);                  ::ReleaseDC(NULL,hDC1);                  DeleteObject(hPal);                   return ;         }         lpbi = (LPBITMAPINFOHEADER)hDIB;         BOOL bGotBits = GetDIBits( hDC1, hBmp,0L,(DWORD)bi.biHeight,(LPBYTE)lpbi+ (bi.biSize + nColors * sizeof(RGBQUAD)),                  (LPBITMAPINFO)lpbi,(DWORD)DIB_RGB_COLORS);         if( !bGotBits )         {                  GlobalFree(hDIB);                  SelectPalette(hDC1,hPal,FALSE);                  ::ReleaseDC(NULL,hDC1);                  DeleteObject(hPal);                   return;         }         if(iWidth==0||iLength==0)         {                  iWidth=lpbi->biWidth;                  iLength=lpbi->biHeight;                  iWidth=(int)(dScaleX*iWidth);                  iLength=(int)(iLength*dScaleY);         }         StretchDIBits(hDC,iX,iY,iWidth,iLength,0,0,lpbi->biWidth,lpbi->biHeight,(LPBYTE)lpbi                     // address for bitmap bits                   + (bi.biSize + nColors * sizeof(RGBQUAD)),(LPBITMAPINFO)lpbi,DIB_RGB_COLORS,SRCCOPY);         SelectPalette(hDC1,hPal,FALSE);         ::ReleaseDC(NULL,hDC1);         DeleteObject(hDIB);         DeleteObject(hPal);}// 附:得到一个DC位图的代码HBITMAP GetSrcBit(HDC hDC,DWORD BitWidth, DWORD BitHeight){         HDC hBufDC;         HBITMAP hBitmap, hBitTemp;         hBufDC = CreateCompatibleDC(hDC);         hBitmap = CreateCompatibleBitmap(hDC, BitWidth, BitHeight);         hBitTemp = (HBITMAP) SelectObject(hBufDC, hBitmap);         StretchBlt(hBufDC, 0, 0, BitWidth, BitHeight,                   hDC, 0, 0, BitWidth, BitHeight, SRCCOPY);         hBitmap = (HBITMAP) SelectObject(hBufDC, hBitTemp);         ::DeleteDC(hBufDC);         return hBitmap;}  
      

  3.   

    楼上不要拿我的东东到处贴:)你的这个问题也容易,你鼠标点击的话就会得到鼠标位置的一个点,然后按照给定大小,得到一个矩形,使用StretchBlt把这个矩形位置的DC复制到你所需要放大的地方就可以了:)StretchBlt
    The StretchBlt function copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if necessary. The system stretches or compresses the bitmap according to the stretching mode currently set in the destination device context. BOOL StretchBlt(
      HDC hdcDest,      // handle to destination DC
      int nXOriginDest, // x-coord of destination upper-left corner
      int nYOriginDest, // y-coord of destination upper-left corner
      int nWidthDest,   // width of destination rectangle
      int nHeightDest,  // height of destination rectangle
      HDC hdcSrc,       // handle to source DC
      int nXOriginSrc,  // x-coord of source upper-left corner
      int nYOriginSrc,  // y-coord of source upper-left corner
      int nWidthSrc,    // width of source rectangle
      int nHeightSrc,   // height of source rectangle
      DWORD dwRop       // raster operation code
    );
    Parameters
    hdcDest 
    [in] Handle to the destination device context. 
    nXOriginDest 
    [in] Specifies the x-coordinate, in logical units, of the upper-left corner of the destination rectangle. 
    nYOriginDest 
    [in] Specifies the y-coordinate, in logical units, of the upper-left corner of the destination rectangle. 
    nWidthDest 
    [in] Specifies the width, in logical units, of the destination rectangle. 
    nHeightDest 
    [in] Specifies the height, in logical units, of the destination rectangle. 
    hdcSrc 
    [in] Handle to the source device context. 
    nXOriginSrc 
    [in] Specifies the x-coordinate, in logical units, of the upper-left corner of the source rectangle. 
    nYOriginSrc 
    [in] Specifies the y-coordinate, in logical units, of the upper-left corner of the source rectangle. 
    nWidthSrc 
    [in] Specifies the width, in logical units, of the source rectangle. 
    nHeightSrc 
    [in] Specifies the height, in logical units, of the source rectangle. 
    dwRop 
    [in] Specifies the raster operation to be performed. Raster operation codes define how the system combines colors in output operations that involve a brush, a source bitmap, and a destination bitmap. 
    See BitBlt for a list of common raster operation codes. 
      

  4.   

    可以考虑用StretchBlt,
    主要问题是源图和目的图的定位,大小控制等
      

  5.   

    以点击位置为中心,取得一个小区域,然后用StretchBlt绘制就行了
      

  6.   

    我有源码的例子,要的话的就将EMAIL贴上吧!
      

  7.   

    浪淘沙,先谢谢你了!我的mail是[email protected].