图像大小调整:我应该做出哪些更正? (窗口应用程序,VC ++)

时间:2016-06-30 07:06:41

标签: c++ image visual-studio resize window

所以我一直坚持使用此图像调整大小问题一段时间:程序显示图像然后根据用户拖动边框时提供的大小调整大小,而不是在图像时剪切图像边框向内拖动或向外拖动时保持原样。

我在主WinAPI中使用了一个显示窗口算法,并在WM_PAINT中提供了缩放算法实例的声明。

我必须从单独的类链接到同一项目中的单独文件中的缩放算法,我已将其包含在标题中(#include" scaling.h")。缩放图像后,我再次将显示调用到窗口,但拖动边框后尺寸没有任何变化。我必须对代码做出哪些更改?

#include <windows.h>
#include <windows.h>
#include <tchar.h>
#include "scaling.h"
HBITMAP hBitmap;
HDC localDC;
HBITMAP hOld;
BITMAP qB;
HDC hDC;                                             // Handle (virtual memory pointer) to drawing characteristics
RECT rect;
PAINTSTRUCT ps;
HDC MemDC;
HBITMAP bmp;
BITMAP bm;

LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam){
switch(msg){
    case WM_CREATE:{
        //MessageBox(hwnd,_T("Window Procedure Received WM_CREATE Message!"),_T("Message Report!"),MB_OK);
        return 0;
    }
    case WM_LBUTTONDOWN: {
        //MessageBox(hwnd,_T("Window Procedure Received WM_LBUTTONDOWN Message!"),_T("Message Report!"),MB_OK);
    return 0;
    }

    case WM_PAINT: {                  //At program start up the whole window is invalid so must be drawn.
        //TCHAR tmpText[]=_T("TempText");
        PAINTSTRUCT ps;      
        hDC = BeginPaint(hwnd,&ps); 
        BOOL qRetBlit = ::BitBlt(hDC,0,0,qB.bmWidth,qB.bmHeight,localDC,0,0,SRCCOPY);

        ::GetClientRect(hwnd, &rect);

        // Create a memory device compatible with the above DC variable
        MemDC = CreateCompatibleDC(hDC);

        // Select the new bitmap
        SelectObject(MemDC, hBitmap);
        GetObject(hBitmap, sizeof(bm), &bm);

        int w2,h2;
        if(GetClientRect(hwnd, &rect))  //In order to obtain the current window's parameters
        {
           w2 = rect.right - rect.left;
           h2 = rect.bottom - rect.top;
        } 

        BYTE *pixels_old = (BYTE *)qB.bmBits;
        scaling sc;
        BYTE *pixels = sc.resizePixels(pixels_old, qB.bmWidth, qB.bmHeight, w2, h2);

        qB.bmBits = pixels;

        MemDC = CreateCompatibleDC(hDC);

        SelectObject(MemDC, &qB);

        hDC = BeginPaint(hwnd,&ps);
        qRetBlit = ::BitBlt(hDC,w2,h2,qB.bmWidth,qB.bmHeight,localDC,0,0,SRCCOPY);

        delete []pixels;
                                  // Return Drawing Context To Original State
        EndPaint(hwnd, &ps);
        return 0;
    }
    case WM_DESTROY: {                    
        ::SelectObject(localDC,hOld);
        ::DeleteDC(localDC);
        ::DeleteObject(hBitmap);
        PostQuitMessage(0);
        return 0;
     }
}
return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int iShow){
TCHAR szClassName[]=_T("Name");
WNDCLASSEX wc;
MSG messages;
HWND hWnd;

wc.lpszClassName  =  szClassName;                     
wc.lpfnWndProc    =  fnWndProc;                       
wc.cbSize         =  sizeof (WNDCLASSEX);             
wc.style          =  0;                               
wc.hIcon          =  LoadIcon(NULL,IDI_APPLICATION);  
wc.hInstance      =  hInstance;                       
wc.hIconSm        =  0; //LoadIcon(wc.hInstance, MAKEINTRESOURCE(IDI_SMALL)); 
wc.hCursor        =  LoadCursor(NULL,IDC_ARROW);      
wc.hbrBackground  =  (HBRUSH)COLOR_BTNSHADOW;         
wc.cbWndExtra     =  0;                               
wc.cbClsExtra     =  0;
wc.lpszMenuName   =  NULL;
RegisterClassEx(&wc);
hBitmap = (HBITMAP)::LoadImage(NULL, _T("D:\\Chrysanthemum.bmp"),IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
GetObject(reinterpret_cast<HGDIOBJ>(hBitmap),sizeof(BITMAP),reinterpret_cast<LPVOID>(&qB));
localDC = ::CreateCompatibleDC(hDC);
hOld = (HBITMAP)::SelectObject(localDC,hBitmap);

hWnd = CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,0,0,qB.bmWidth,qB.bmHeight,HWND_DESKTOP,0,hInstance,0);
ShowWindow(hWnd,iShow);
while(GetMessage(&messages,NULL,0,0)){                                                   
    TranslateMessage(&messages);                     
    DispatchMessage(&messages);
}
return (int)messages.wParam;
}

来自&#34; Scaling.h&#34;的缩放算法如下:(最近邻居

#include <iostream>
class scaling{
public:
BYTE* resizePixels(BYTE* pixels,int w1,int h1,int w2,int h2) 
{
    BYTE* retval = new BYTE[w2*h2] ;
// EDIT: added +1 to remedy an early rounding problem
int x_ratio = (int)((w1<<16)/w2) +1;
int y_ratio = (int)((h1<<16)/h2) +1;
//int x_ratio = (int)((w1<<16)/w2) ;
//int y_ratio = (int)((h1<<16)/h2) ;
int x2, y2 ;
for (int i=0;i<h2;i++) {
    for (int j=0;j<w2;j++) {
        x2 = ((j*x_ratio)>>16) ;
        y2 = ((i*y_ratio)>>16) ;
        retval[(i*w2)+j] = pixels[(y2*w1)+x2] ;
    }                
}                
return retval;
}
};

提前致谢!

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

使用StretchBlt轻松自如。我认为你的伸展算法是错误的。
https://msdn.microsoft.com/en-us/library/windows/desktop/dd145120(v=vs.85).aspx