📄 viewer24.cpp
字号:
#include <windows.h>
#include <stdio.h>
#include <float.h>
#include "images.h"
char* caption;
char* filename;
//---------------------------------------------------------------------------
long FAR PASCAL WndProc
(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
static int imdims;
static int* imdim;
static int quantity, xdim, ydim, zdim;
static int imtype;
static mgcImageFile* imfile;
static float* imdata = 0;;
static float min = FLT_MAX;
static float max = -FLT_MAX;
static float range;
static char* bmi = 0;
static HBITMAP hImage;
static DWORD* bits;
static int x, y, z;
static BOOL ButtonDown = FALSE;
static HDC dragDC;
static BOOL display_caption = FALSE;
static char* pixelstr;
switch ( message ) {
case WM_CREATE:
{
int k;
// get requested image
imfile = new mgcImageFile(filename,&imdims,&imdim,&imtype);
xdim = imdim[0];
ydim = imdim[1];
if ( imdims == 2 )
zdim = 1;
if ( imdims == 3 )
zdim = imdim[2];
// allocate image memory for single slice
quantity = xdim*ydim;
if ( imtype != mgcRGB8::type )
{
imdata = new float[quantity];
if ( !imdata )
return -1;
}
// allocate bit map
bits = new DWORD[quantity];
if ( !bits )
return -1;
for (k = 0; k < quantity; k++)
bits[k] = 0;
if ( imtype != mgcRGB8::type )
{
// compute image min and max
for (z = 0; z < zdim; z++)
{
imfile->Get(mgcFloat::type,imdata,z*quantity,quantity);
for (k = 0; k < quantity; k++)
{
if ( imdata[k] < min )
min = imdata[k];
if ( imdata[k] > max )
max = imdata[k];
}
}
range = max-min;
}
// get slice 0
z = 0;
if ( imtype != mgcRGB8::type )
{
imfile->Get(mgcFloat::type,imdata,0,quantity);
if ( range > 0 ) // image is not constant
for (k = 0; k < quantity; k++)
{
DWORD gray = DWORD(255*(imdata[k]-min)/range);
bits[k] = gray + (gray << 8) + (gray << 16);
}
}
else
{
imfile->Get(mgcRGB8::type,bits,0,quantity);
}
// create the bitmap
bmi = new char[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD*)];
BITMAPINFOHEADER& bmih = *(BITMAPINFOHEADER*)bmi;
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = xdim;
bmih.biHeight = -ydim;
bmih.biPlanes = 1;
bmih.biBitCount = 32;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = xdim*ydim;
bmih.biXPelsPerMeter = 0;
bmih.biYPelsPerMeter = 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
HDC hdc = GetDC(hwnd);
hImage = CreateDIBitmap(
hdc,
&bmih,
CBM_INIT,
(const void*) bits,
(const BITMAPINFO*) bmi,
DIB_RGB_COLORS
);
ReleaseDC(hwnd,hdc);
// allocate string for pixel display
pixelstr = new char[128];
return 0;
}
case WM_DESTROY: {
// deallocate application memory and handles
delete[] bmi;
delete[] bits;
delete[] pixelstr;
if ( imtype != mgcRGB8::type )
delete[] imdata;
delete imfile;
DeleteObject(hImage);
// send WM_QUIT message to Windows to terminate application
PostQuitMessage(0);
} return 0;
case WM_PAINT: {
// client area needs to be redrawn
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd,&ps);
HDC imageDC = CreateCompatibleDC(hdc);
// get the image bitmap and redraw it
BITMAP bm;
GetObject(hImage,sizeof(BITMAP),&bm);
SelectObject(imageDC,hImage);
BitBlt(hdc,0,0,bm.bmWidth,bm.bmHeight,imageDC,0,0,SRCCOPY);
DeleteDC(imageDC);
EndPaint(hwnd,&ps);
} return 0;
case WM_LBUTTONDOWN: {
// read and display pixel value at mouse location
if ( ButtonDown == FALSE ) {
ButtonDown = TRUE;
SetCapture(hwnd); // let window have control of mouse events
dragDC = GetDC(hwnd);
x = LOWORD(lParam);
y = HIWORD(lParam);
if ( 0 <= x && x < xdim && 0 <= y && y < ydim ) {
int index = x+xdim*y;
if ( imtype != mgcRGB8::type )
{
if ( zdim == 1 )
sprintf(pixelstr,"(%d,%d) %f",x,y,imdata[index]);
else
sprintf(pixelstr,"(%d,%d,%d) %f",x,y,z,imdata[index]);
}
else
{
unsigned int value = bits[index];
if ( zdim == 1 )
{
sprintf(pixelstr,"(%d,%d) r=%d g=%d b=%d",x,y,
mgcRGB8::GetRed(value),
mgcRGB8::GetGreen(value),
mgcRGB8::GetBlue(value));
}
else
{
sprintf(pixelstr,"(%d,%d,%d) r=%d g=%d b=%d",x,y,z,
mgcRGB8::GetRed(value),
mgcRGB8::GetGreen(value),
mgcRGB8::GetBlue(value));
}
}
SetWindowText(hwnd,pixelstr);
display_caption = TRUE;
}
}
} return 0;
case WM_MOUSEMOVE: {
// allow mouse dragging for continuous update/display of pixel values
if ( ButtonDown == TRUE ) {
x = LOWORD(lParam);
y = HIWORD(lParam);
if ( 0 <= x && x < xdim && 0 <= y && y < ydim ) {
int index = x+xdim*y;
if ( imtype != mgcRGB8::type )
{
if ( zdim == 1 )
sprintf(pixelstr,"(%d,%d) %f",x,y,imdata[index]);
else
sprintf(pixelstr,"(%d,%d,%d) %f",x,y,z,imdata[index]);
}
else
{
unsigned int value = bits[index];
if ( zdim == 1 )
{
sprintf(pixelstr,"(%d,%d) r=%d g=%d b=%d",x,y,
mgcRGB8::GetRed(value),
mgcRGB8::GetGreen(value),
mgcRGB8::GetBlue(value));
}
else
{
sprintf(pixelstr,"(%d,%d,%d) r=%d g=%d b=%d",x,y,z,
mgcRGB8::GetRed(value),
mgcRGB8::GetGreen(value),
mgcRGB8::GetBlue(value));
}
}
SetWindowText(hwnd,pixelstr);
display_caption = TRUE;
}
else if ( display_caption == TRUE ) {
// mouse outside of client area, redisplay window caption once
SetWindowText(hwnd,caption);
display_caption = FALSE;
}
}
} return 0;
case WM_LBUTTONUP: {
// finished reading pixel values, redisplay window caption
if ( ButtonDown == TRUE ) {
ButtonDown = FALSE;
ReleaseCapture(); // window gives up control of mouse events
ReleaseDC(hwnd,dragDC);
SetWindowText(hwnd,caption);
display_caption = FALSE;
}
} return 0;
case WM_KEYDOWN: {
switch ( wParam ) {
case VK_UP: {
// up-arrow pressed, go to next image slize
if ( z < zdim-1 ) {
z++;
// get slice and convert image values to palette indices
if ( imtype != mgcRGB8::type)
{
imfile->Get(mgcFloat::type,imdata,z*quantity,quantity);
if ( range > 0 )
for (int k = 0; k < quantity; k++)
{
DWORD gray = DWORD(255*(imdata[k]-min)/range);
bits[k] = gray + (gray << 8) + (gray << 16);
}
}
else
{
imfile->Get(mgcRGB8::type,bits,z*quantity,quantity);
}
// update bitmap and redraw client area
HDC hdc = GetDC(hwnd);
SetDIBits(
hdc,
hImage,
0,
ydim,
(const void*) bits,
(const BITMAPINFO*) bmi,
DIB_RGB_COLORS
);
ReleaseDC(hwnd,hdc);
InvalidateRect(hwnd,NULL,FALSE);
}
} break;
case VK_DOWN: {
// down-arrow pressed, go to previous image slice
if ( z > 0 ) {
z--;
// get slice and convert image values to palette indices
if ( imtype != mgcRGB8::type )
{
imfile->Get(mgcFloat::type,imdata,z*quantity,quantity);
if ( range > 0 )
for (int k = 0; k < quantity; k++)
{
DWORD gray = DWORD(255*(imdata[k]-min)/range);
bits[k] = gray + (gray << 8) + (gray << 16);
}
}
else
{
imfile->Get(mgcRGB8::type,bits,z*quantity,quantity);
}
// update bitmap and redraw client area
HDC hdc = GetDC(hwnd);
SetDIBits(
hdc,
hImage,
0,
ydim,
(const void*) bits,
(const BITMAPINFO*) bmi,
DIB_RGB_COLORS
);
ReleaseDC(hwnd,hdc);
InvalidateRect(hwnd,NULL,FALSE);
}
} break;
}
} return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
//---------------------------------------------------------------------------
int PASCAL WinMain
(
HINSTANCE hInstance, // handle of current instance
HINSTANCE hPrevInstance, // handle of previous instance
LPSTR lpszCmdLine, // address of command line
int nCmdShow // show state of window
)
{
static char szAppName[] = "Viewer24";
if ( !hPrevInstance ) {
// first instance of application, so register the window class
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
RegisterClass(&wc);
}
// Get the command line and strip off the stupid double quotes
// Win32 puts around the command string. Win32s did not do this.
filename = new char[strlen(lpszCmdLine)+1];
if ( lpszCmdLine[0] == '\"' ) {
strcpy(filename,lpszCmdLine+1); // remove leading quote
if ( lpszCmdLine[strlen(lpszCmdLine)-1] == '\"' )
filename[strlen(lpszCmdLine)-2] = '\0'; // remove trailing quote
}
else
strcpy(filename,lpszCmdLine);
// get the image header, support only 2D and 3D images
int dims;
int* dim;
int type;
mgcImageFile file(filename,&dims,&dim,&type);
if ( file.error ) {
MessageBox(NULL,filename,"cannot open file",MB_OK);
return NULL;
}
if ( dims < 2 || dims > 3 ) {
MessageBox(NULL,filename,"not a 2D or 3D image",MB_OK);
return NULL;
}
// strip off path and use filename for window caption
caption = strrchr(filename,'\\');
if ( caption )
caption++;
else
caption = filename;
// compute image size and create window of appropriate client size
RECT rect = { 0, 0, dim[0]-1, dim[1]-1 };
AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,NULL);
HWND hwnd = CreateWindow (
szAppName, // window class name
caption, // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
rect.right-rect.left+1, // initial x size
rect.bottom-rect.top+1, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL // creation parameters
);
ShowWindow(hwnd,nCmdShow); // display the window on the screen
UpdateWindow(hwnd); // draw the client area
MSG wmsg;
while ( GetMessage(&wmsg,NULL,0,0) ) {
TranslateMessage(&wmsg); // translate virtual key codes for WM_CHAR
DispatchMessage(&wmsg); // send to application message queue
}
delete[] filename;
return wmsg.wParam;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -