-1

So I've been stuck with this image resizing problem for a while: The program displays an image and then resizes it according to the size provided by the user when they drag the border, rather than clipping the image when the border is dragged inward or leaving it as it is when dragged outward.

I used a Display Window algorithm in the main WinAPI, and provided the declaration of an instance of the scaling algorithm in WM_PAINT.

I have to link to the scaling algorithm from a separate class from a separate file in the same project, which I've included in the header (#include"scaling.h"). After scaling the image I've called the display to the window again, but there aren't any changes in the size after dragging the border. What changes would I have to make to the code?

#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;
}

The scaling algorithm from "Scaling.h" is as follows: (nearest neighbour)

#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;
}
};

Thanks in advance!

  • I'm surprised this is displaying anything whatsoever. Your `SelectObject(MemDC, &qB)` is passing a pointer rather than a handle, so it shouldn't work at all. – Mark Ransom Jul 01 '16 at 04:38
  • It displays only the first part, not the scaled image. Hmm, I'll give that a look, thanks. – Midhav Ravindran Jul 01 '16 at 06:08

2 Answers2

0

read before asking: Image scaling and rotating in C/C++ http://www.cplusplus.com/forum/general/2615/

https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd183402(v=vs.85).aspx

Community
  • 1
  • 1
Alexandr
  • 154
  • 1
  • 7
  • I have already chosen an algorithm for the purpose of scaling, it's just that something in my implementation is screwed up. – Midhav Ravindran Jun 30 '16 at 10:31
  • Link only answers are not accepted. Some of your links don't seem to be relevant at all. Please see http://stackoverflow.com/help/how-to-answer – Barmak Shemirani Jul 01 '16 at 04:07
0

use StretchBlt its ease. I think the is an error in your stretch algoritm.
https://msdn.microsoft.com/en-us/library/windows/desktop/dd145120(v=vs.85).aspx

Alexandr
  • 154
  • 1
  • 7
  • Ah well I've done it with StretchBlt already. The task given to me was to try calling a function from another file for stretching. The stretching part works (I used some file operations and found out that the size in fact changes as I wanted it to, from the values I'd later added to w2, h2). So there's something wrong with the display part. – Midhav Ravindran Jul 01 '16 at 06:06
  • There is error's in your code. trace hDC in your code. You call BeginPaint twice! Try write from scratchю – Alexandr Jul 01 '16 at 09:05
  • Ah thanks! Anyway, I removed BeginPaint, but I suppose qRetBlit still has to be called again right? – Midhav Ravindran Jul 01 '16 at 09:43
  • I don;t know. Try to rewrite your program.there must be something like this:1.Load image. 2. create compatible DC. 3.select bitmap in this DC. 4. Bitblt from this DC to window DC(BeginPaint()). And if you whant to resize, i think it's must be after '3' – Alexandr Jul 01 '16 at 10:57