mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:56:26 +00:00
I modified this StretchBlt sample to provide non-uniform scaling of image, plus two ways to scale it - via stretchblt() and via stretchdibits() -- to test both functions in ReactOS.
If anyone is strictly against me modifiying this sample from the book -- tell me, and I will create stretchblt2 then. But I think this is unncessary. svn path=/trunk/; revision=8347
This commit is contained in:
parent
b13d239f87
commit
dcbe451792
1 changed files with 155 additions and 41 deletions
|
@ -10,14 +10,22 @@
|
||||||
// if you have any questions about this code.
|
// if you have any questions about this code.
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Modified by Aleksey Bragin (aleksey at studiocerebral.com)
|
||||||
|
// to support non-uniform scaling, and output via sretchdibits
|
||||||
|
// (type something in the command line to invoke this mode,
|
||||||
|
// in future it will be source BPP)
|
||||||
|
|
||||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
|
||||||
|
|
||||||
HWND HListBox = NULL;
|
HWND HListBox = NULL;
|
||||||
|
HWND VListBox = NULL;
|
||||||
const int ID_LISTBOX = 101;
|
const int ID_LISTBOX = 101;
|
||||||
|
const int ID_LISTBOX2 = 102;
|
||||||
|
BOOL useDIBits=FALSE; // How to display the image - via StretchDIBits
|
||||||
|
|
||||||
HINSTANCE HInst;
|
HINSTANCE HInst;
|
||||||
HINSTANCE HPrevInst;
|
HINSTANCE HPrevInst;
|
||||||
|
@ -47,7 +55,7 @@ int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance,
|
||||||
if (RegisterClass(&wc))
|
if (RegisterClass(&wc))
|
||||||
{
|
{
|
||||||
HWND HWnd =
|
HWND HWnd =
|
||||||
CreateWindow(WndClassName, TEXT("StretchBlt Zooming Demo"),
|
CreateWindow(WndClassName, TEXT("StretchBlt NonUniform Zooming Demo"),
|
||||||
WS_OVERLAPPEDWINDOW | WS_CAPTION |
|
WS_OVERLAPPEDWINDOW | WS_CAPTION |
|
||||||
WS_VISIBLE | WS_CLIPSIBLINGS,
|
WS_VISIBLE | WS_CLIPSIBLINGS,
|
||||||
0, 0, 675, 560,
|
0, 0, 675, 560,
|
||||||
|
@ -61,8 +69,16 @@ int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance,
|
||||||
530, 5, 130, 150, HWnd,
|
530, 5, 130, 150, HWnd,
|
||||||
reinterpret_cast<HMENU>(ID_LISTBOX),
|
reinterpret_cast<HMENU>(ID_LISTBOX),
|
||||||
HInst, NULL);
|
HInst, NULL);
|
||||||
if (HListBox)
|
VListBox =
|
||||||
|
CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "",
|
||||||
|
LBS_NOTIFY | WS_CHILD | WS_VISIBLE,
|
||||||
|
530, 5+170, 130, 150, HWnd,
|
||||||
|
reinterpret_cast<HMENU>(ID_LISTBOX2),
|
||||||
|
HInst, NULL);
|
||||||
|
|
||||||
|
if (HListBox && VListBox)
|
||||||
{
|
{
|
||||||
|
// horizontal zoom
|
||||||
SNDMSG(HListBox, LB_ADDSTRING, 0,
|
SNDMSG(HListBox, LB_ADDSTRING, 0,
|
||||||
reinterpret_cast<LPARAM>("Zoom 25%"));
|
reinterpret_cast<LPARAM>("Zoom 25%"));
|
||||||
SNDMSG(HListBox, LB_ADDSTRING, 0,
|
SNDMSG(HListBox, LB_ADDSTRING, 0,
|
||||||
|
@ -79,6 +95,24 @@ int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance,
|
||||||
reinterpret_cast<LPARAM>("Zoom 200%"));
|
reinterpret_cast<LPARAM>("Zoom 200%"));
|
||||||
SNDMSG(HListBox, LB_ADDSTRING, 0,
|
SNDMSG(HListBox, LB_ADDSTRING, 0,
|
||||||
reinterpret_cast<LPARAM>("Zoom 300%"));
|
reinterpret_cast<LPARAM>("Zoom 300%"));
|
||||||
|
// vertical zoom
|
||||||
|
SNDMSG(VListBox, LB_ADDSTRING, 0,
|
||||||
|
reinterpret_cast<LPARAM>("Zoom 25%"));
|
||||||
|
SNDMSG(VListBox, LB_ADDSTRING, 0,
|
||||||
|
reinterpret_cast<LPARAM>("Zoom 50%"));
|
||||||
|
SNDMSG(VListBox, LB_ADDSTRING, 0,
|
||||||
|
reinterpret_cast<LPARAM>("Zoom 75%"));
|
||||||
|
SNDMSG(VListBox, LB_ADDSTRING, 0,
|
||||||
|
reinterpret_cast<LPARAM>("Zoom 100%"));
|
||||||
|
SNDMSG(VListBox, LB_ADDSTRING, 0,
|
||||||
|
reinterpret_cast<LPARAM>("Zoom 125%"));
|
||||||
|
SNDMSG(VListBox, LB_ADDSTRING, 0,
|
||||||
|
reinterpret_cast<LPARAM>("Zoom 150%"));
|
||||||
|
SNDMSG(VListBox, LB_ADDSTRING, 0,
|
||||||
|
reinterpret_cast<LPARAM>("Zoom 200%"));
|
||||||
|
SNDMSG(VListBox, LB_ADDSTRING, 0,
|
||||||
|
reinterpret_cast<LPARAM>("Zoom 300%"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowWindow(HWnd, nCmdShow);
|
ShowWindow(HWnd, nCmdShow);
|
||||||
|
@ -99,12 +133,15 @@ int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance,
|
||||||
|
|
||||||
// image related
|
// image related
|
||||||
BITMAP bmp;
|
BITMAP bmp;
|
||||||
|
BITMAPINFO bmInfo;
|
||||||
|
char *bbits = NULL; // bitmap bits
|
||||||
const char* filename = "LENA.BMP";
|
const char* filename = "LENA.BMP";
|
||||||
HDC HMemDC = NULL;
|
HDC HMemDC = NULL;
|
||||||
HBITMAP HOldBmp = NULL;
|
HBITMAP HOldBmp = NULL;
|
||||||
|
|
||||||
// zooming related
|
// zooming related
|
||||||
float zoom_factor = 0.5;
|
float zoom_factor_h = 0.5;
|
||||||
|
float zoom_factor_v = 0.5;
|
||||||
RECT RDest = {5, 5, 0, 0};
|
RECT RDest = {5, 5, 0, 0};
|
||||||
enum {ID_ZOOM25, ID_ZOOM50, ID_ZOOM75, ID_ZOOM100,
|
enum {ID_ZOOM25, ID_ZOOM50, ID_ZOOM75, ID_ZOOM100,
|
||||||
ID_ZOOM125, ID_ZOOM150, ID_ZOOM200, ID_ZOOM300};
|
ID_ZOOM125, ID_ZOOM150, ID_ZOOM200, ID_ZOOM300};
|
||||||
|
@ -116,6 +153,15 @@ LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam,
|
||||||
{
|
{
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
{
|
{
|
||||||
|
// check commandline
|
||||||
|
if (strlen(cmdline) != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
useDIBits = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
useDIBits = FALSE;
|
||||||
|
|
||||||
// create a memory DC
|
// create a memory DC
|
||||||
HMemDC = CreateCompatibleDC(NULL);
|
HMemDC = CreateCompatibleDC(NULL);
|
||||||
if (HMemDC)
|
if (HMemDC)
|
||||||
|
@ -131,34 +177,76 @@ LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam,
|
||||||
// extract dimensions of the bitmap
|
// extract dimensions of the bitmap
|
||||||
GetObject(HBmp, sizeof(BITMAP), &bmp);
|
GetObject(HBmp, sizeof(BITMAP), &bmp);
|
||||||
|
|
||||||
// associate the bitmap with the memory DC
|
// fill the BITMAPINFO stucture for further use by StretchDIBits
|
||||||
|
bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
bmInfo.bmiHeader.biWidth = bmp.bmWidth;
|
||||||
|
bmInfo.bmiHeader.biHeight = bmp.bmHeight;
|
||||||
|
bmInfo.bmiHeader.biPlanes = 1;//bmp.bmPlanes;
|
||||||
|
bmInfo.bmiHeader.biBitCount = bmp.bmBitsPixel;
|
||||||
|
bmInfo.bmiHeader.biCompression = BI_RGB;
|
||||||
|
bmInfo.bmiHeader.biSizeImage = 0;
|
||||||
|
bmInfo.bmiHeader.biXPelsPerMeter = 0;
|
||||||
|
bmInfo.bmiHeader.biClrImportant = 0;
|
||||||
|
bmInfo.bmiHeader.biClrUsed = 0;
|
||||||
|
|
||||||
|
// associate the bitmap with the memory DC
|
||||||
HOldBmp = static_cast<HBITMAP>(
|
HOldBmp = static_cast<HBITMAP>(
|
||||||
SelectObject(HMemDC, HBmp)
|
SelectObject(HMemDC, HBmp)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (useDIBits)
|
||||||
|
{
|
||||||
|
bbits = new char[bmp.bmHeight*bmp.bmWidthBytes*(bmp.bmBitsPixel / 8)];
|
||||||
|
//GetDIBits(HMemDC, HBmp, 0, bmp.bmHeight, bbits, &bmInfo, DIB_RGB_COLORS);
|
||||||
|
|
||||||
|
// Here goes a temp hack, since GetDIBits doesn't exist in ReactOS yet
|
||||||
|
FILE *f = fopen(filename, "rb");
|
||||||
|
BITMAPFILEHEADER bmpHeader;
|
||||||
|
|
||||||
|
fread(&bmpHeader, sizeof(BITMAPFILEHEADER), 1, f);
|
||||||
|
fread(&bmInfo, sizeof(BITMAPINFO), 1, f);
|
||||||
|
fseek(f, bmpHeader.bfOffBits, SEEK_SET);
|
||||||
|
fread(bbits, bmp.bmHeight*bmp.bmWidthBytes*(bmp.bmBitsPixel / 8), 1, f);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
{
|
{
|
||||||
if (WParam == MAKEWPARAM(ID_LISTBOX, LBN_SELCHANGE))
|
if (WParam == MAKEWPARAM(ID_LISTBOX, LBN_SELCHANGE) ||
|
||||||
|
WParam == MAKEWPARAM(ID_LISTBOX2, LBN_SELCHANGE))
|
||||||
{
|
{
|
||||||
switch (SNDMSG(HListBox, LB_GETCURSEL, 0, 0))
|
switch (SNDMSG(HListBox, LB_GETCURSEL, 0, 0))
|
||||||
{
|
{
|
||||||
case ID_ZOOM25: zoom_factor = 0.25; break;
|
case ID_ZOOM25: zoom_factor_h = 0.25; break;
|
||||||
case ID_ZOOM50: zoom_factor = 0.50; break;
|
case ID_ZOOM50: zoom_factor_h = 0.50; break;
|
||||||
case ID_ZOOM75: zoom_factor = 0.75; break;
|
case ID_ZOOM75: zoom_factor_h = 0.75; break;
|
||||||
case ID_ZOOM100: zoom_factor = 1.00; break;
|
case ID_ZOOM100: zoom_factor_h = 1.00; break;
|
||||||
case ID_ZOOM125: zoom_factor = 1.25; break;
|
case ID_ZOOM125: zoom_factor_h = 1.25; break;
|
||||||
case ID_ZOOM150: zoom_factor = 1.50; break;
|
case ID_ZOOM150: zoom_factor_h = 1.50; break;
|
||||||
case ID_ZOOM200: zoom_factor = 2.00; break;
|
case ID_ZOOM200: zoom_factor_h = 2.00; break;
|
||||||
case ID_ZOOM300: zoom_factor = 3.00; break;
|
case ID_ZOOM300: zoom_factor_h = 3.00; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (SNDMSG(VListBox, LB_GETCURSEL, 0, 0))
|
||||||
|
{
|
||||||
|
case ID_ZOOM25: zoom_factor_v = 0.25; break;
|
||||||
|
case ID_ZOOM50: zoom_factor_v = 0.50; break;
|
||||||
|
case ID_ZOOM75: zoom_factor_v = 0.75; break;
|
||||||
|
case ID_ZOOM100: zoom_factor_v = 1.00; break;
|
||||||
|
case ID_ZOOM125: zoom_factor_v = 1.25; break;
|
||||||
|
case ID_ZOOM150: zoom_factor_v = 1.50; break;
|
||||||
|
case ID_ZOOM200: zoom_factor_v = 2.00; break;
|
||||||
|
case ID_ZOOM300: zoom_factor_v = 3.00; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the new width and height
|
// calculate the new width and height
|
||||||
const int new_width =
|
const int new_width =
|
||||||
static_cast<int>(zoom_factor * bmp.bmWidth);
|
static_cast<int>(zoom_factor_h * bmp.bmWidth);
|
||||||
const int new_height =
|
const int new_height =
|
||||||
static_cast<int>(zoom_factor * bmp.bmHeight);
|
static_cast<int>(zoom_factor_v * bmp.bmHeight);
|
||||||
|
|
||||||
// is zooming in?
|
// is zooming in?
|
||||||
bool zoom_in = (new_width > RDest.right - RDest.left);
|
bool zoom_in = (new_width > RDest.right - RDest.left);
|
||||||
|
@ -210,34 +298,57 @@ LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam,
|
||||||
//
|
//
|
||||||
// TODO: add palette support (see Chapter 9)...
|
// TODO: add palette support (see Chapter 9)...
|
||||||
//
|
//
|
||||||
|
if (useDIBits)
|
||||||
|
{
|
||||||
|
if (RDest.right - RDest.left > 0)
|
||||||
|
{
|
||||||
|
if (zoom_factor_h < 1.0 || zoom_factor_v < 1.0)
|
||||||
|
{
|
||||||
|
SetStretchBltMode(Hdc, COLORONCOLOR);
|
||||||
|
}
|
||||||
|
|
||||||
if (RDest.right - RDest.left > 0)
|
// render the zoomed image
|
||||||
{
|
StretchDIBits(Hdc, RDest.left, RDest.top,
|
||||||
// use BitBlt when not zooming
|
RDest.right - RDest.left,
|
||||||
if (zoom_factor == 1.0)
|
RDest.bottom - RDest.top,
|
||||||
{
|
0, 0,
|
||||||
BitBlt(Hdc, RDest.left, RDest.top,
|
bmp.bmWidth, bmp.bmHeight,
|
||||||
RDest.right - RDest.left,
|
bbits, &bmInfo,
|
||||||
RDest.bottom - RDest.top,
|
DIB_RGB_COLORS,
|
||||||
HMemDC, 0, 0,
|
SRCCOPY);
|
||||||
SRCCOPY);
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (zoom_factor < 1.0)
|
if (RDest.right - RDest.left > 0)
|
||||||
{
|
{
|
||||||
SetStretchBltMode(Hdc, COLORONCOLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// render the zoomed image
|
// use BitBlt when not zooming
|
||||||
StretchBlt(Hdc, RDest.left, RDest.top,
|
if (zoom_factor_h == 1.0 && zoom_factor_v == 1.0)
|
||||||
RDest.right - RDest.left,
|
{
|
||||||
RDest.bottom - RDest.top,
|
BitBlt(Hdc, RDest.left, RDest.top,
|
||||||
HMemDC, 0, 0,
|
RDest.right - RDest.left,
|
||||||
bmp.bmWidth, bmp.bmHeight,
|
RDest.bottom - RDest.top,
|
||||||
SRCCOPY);
|
HMemDC, 0, 0,
|
||||||
}
|
SRCCOPY);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (zoom_factor_h < 1.0 || zoom_factor_v < 1.0)
|
||||||
|
{
|
||||||
|
SetStretchBltMode(Hdc, COLORONCOLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// render the zoomed image
|
||||||
|
StretchBlt(Hdc, RDest.left, RDest.top,
|
||||||
|
RDest.right - RDest.left,
|
||||||
|
RDest.bottom - RDest.top,
|
||||||
|
HMemDC, 0, 0,
|
||||||
|
bmp.bmWidth, bmp.bmHeight,
|
||||||
|
SRCCOPY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
catch (...)
|
catch (...)
|
||||||
|
@ -254,6 +365,9 @@ LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam,
|
||||||
DeleteObject(SelectObject(HMemDC, HOldBmp));
|
DeleteObject(SelectObject(HMemDC, HOldBmp));
|
||||||
DeleteDC(HMemDC);
|
DeleteDC(HMemDC);
|
||||||
|
|
||||||
|
if (bbits)
|
||||||
|
delete bbits;
|
||||||
|
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue