musicc
asked on
LoadPic program help
Hi,
I am having a problem with LoadPic dealing with streaming images. Basically, I modified the code so that it would read jpeg image and then display the image insquence like a movie. But I'm having making it load faster or smoother. My goal to make it display 15 images per sec if possible. Plz take a look.
//---------------part of the code---------------------- ---------- //
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
char buf[64];
i = i%9;
sprintf(buf,"frame%06d.jpg ",i+1); LoadPictureFile(buf);
hdc = BeginPaint(hWnd, &ps);
if (gpPicture)
{
// get width and height of picture
long hmWidth;
long hmHeight;
gpPicture->get_Width(&hmWi dth);
gpPicture->get_Height(&hmH eight);
// convert himetric to pixels
int nWidth = MulDiv(hmWidth, GetDeviceCaps(hdc, LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, GetDeviceCaps(hdc, LOGPIXELSY), HIMETRIC_INCH);
RECT rc;
GetClientRect(hWnd, &rc);
// display picture using IPicture::Render
gpPicture->Render(hdc, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
}
EndPaint(hWnd, &ps);
i = i+1;
return DefWindowProc(hWnd, message, wParam, lParam);
}
//----------------------pa rt of the code end----------------------- ------//
My loadpic program
// LoadPic.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include <fstream.h>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
int i = 1;
#define MAX_LOADSTRING 100
#define HIMETRIC_INCH 2540
#define MAP_LOGHIM_TO_PIX(x,ppli) ( ((ppli)*(x) + HIMETRIC_INCH/2) / HIMETRIC_INCH )
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRI NG]; // The title bar text
LPPICTURE gpPicture;
HWND ghWnd;
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_LOADPIC, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance) ;
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (gpPicture)
gpPicture->Release();
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_LOADPIC);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_LOADPIC;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
gpPicture = NULL;
ghWnd = hWnd = CreateWindow(szWindowClass , szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
// This function loads a file into an IStream.
void LoadPictureFile(LPCTSTR szFile)
{
// open file
HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
_ASSERTE(INVALID_HANDLE_VA LUE != hFile);
// get file size
DWORD dwFileSize = GetFileSize(hFile, NULL);
_ASSERTE(-1 != dwFileSize);
LPVOID pvData = NULL;
// alloc memory based on file size
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
_ASSERTE(NULL != hGlobal);
pvData = GlobalLock(hGlobal);
_ASSERTE(NULL != pvData);
DWORD dwBytesRead = 0;
// read file and store in global memory
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
_ASSERTE(FALSE != bRead);
GlobalUnlock(hGlobal);
CloseHandle(hFile);
LPSTREAM pstm = NULL;
// create IStream* from global memory
HRESULT hr = CreateStreamOnHGlobal(hGlo bal, TRUE, &pstm);
_ASSERTE(SUCCEEDED(hr) && pstm);
// Create IPicture from image file
if (gpPicture)
gpPicture->Release();
hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);
_ASSERTE(SUCCEEDED(hr) && gpPicture);
pstm->Release();
InvalidateRect(ghWnd, NULL, TRUE);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
char buf[64];
i = i%9;
sprintf(buf,"frame%06d.jpg ",i+1);
LoadPictureFile(buf);
hdc = BeginPaint(hWnd, &ps);
if (gpPicture)
{
// get width and height of picture
long hmWidth;
long hmHeight;
gpPicture->get_Width(&hmWi dth);
gpPicture->get_Height(&hmH eight);
// convert himetric to pixels
int nWidth = MulDiv(hmWidth, GetDeviceCaps(hdc, LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, GetDeviceCaps(hdc, LOGPIXELSY), HIMETRIC_INCH);
RECT rc;
GetClientRect(hWnd, &rc);
// display picture using IPicture::Render
gpPicture->Render(hdc, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
}
EndPaint(hWnd, &ps);
i = i+1;
return DefWindowProc(hWnd, message, wParam, lParam);
}
I am having a problem with LoadPic dealing with streaming images. Basically, I modified the code so that it would read jpeg image and then display the image insquence like a movie. But I'm having making it load faster or smoother. My goal to make it display 15 images per sec if possible. Plz take a look.
//---------------part of the code----------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
char buf[64];
i = i%9;
sprintf(buf,"frame%06d.jpg
hdc = BeginPaint(hWnd, &ps);
if (gpPicture)
{
// get width and height of picture
long hmWidth;
long hmHeight;
gpPicture->get_Width(&hmWi
gpPicture->get_Height(&hmH
// convert himetric to pixels
int nWidth = MulDiv(hmWidth, GetDeviceCaps(hdc, LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, GetDeviceCaps(hdc, LOGPIXELSY), HIMETRIC_INCH);
RECT rc;
GetClientRect(hWnd, &rc);
// display picture using IPicture::Render
gpPicture->Render(hdc, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
}
EndPaint(hWnd, &ps);
i = i+1;
return DefWindowProc(hWnd, message, wParam, lParam);
}
//----------------------pa
My loadpic program
// LoadPic.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include <fstream.h>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
int i = 1;
#define MAX_LOADSTRING 100
#define HIMETRIC_INCH 2540
#define MAP_LOGHIM_TO_PIX(x,ppli) ( ((ppli)*(x) + HIMETRIC_INCH/2) / HIMETRIC_INCH )
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRI
LPPICTURE gpPicture;
HWND ghWnd;
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_LOADPIC, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance)
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (gpPicture)
gpPicture->Release();
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_LOADPIC);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_LOADPIC;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
gpPicture = NULL;
ghWnd = hWnd = CreateWindow(szWindowClass
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
// This function loads a file into an IStream.
void LoadPictureFile(LPCTSTR szFile)
{
// open file
HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
_ASSERTE(INVALID_HANDLE_VA
// get file size
DWORD dwFileSize = GetFileSize(hFile, NULL);
_ASSERTE(-1 != dwFileSize);
LPVOID pvData = NULL;
// alloc memory based on file size
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE,
_ASSERTE(NULL != hGlobal);
pvData = GlobalLock(hGlobal);
_ASSERTE(NULL != pvData);
DWORD dwBytesRead = 0;
// read file and store in global memory
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
_ASSERTE(FALSE != bRead);
GlobalUnlock(hGlobal);
CloseHandle(hFile);
LPSTREAM pstm = NULL;
// create IStream* from global memory
HRESULT hr = CreateStreamOnHGlobal(hGlo
_ASSERTE(SUCCEEDED(hr) && pstm);
// Create IPicture from image file
if (gpPicture)
gpPicture->Release();
hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);
_ASSERTE(SUCCEEDED(hr) && gpPicture);
pstm->Release();
InvalidateRect(ghWnd, NULL, TRUE);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
char buf[64];
i = i%9;
sprintf(buf,"frame%06d.jpg
LoadPictureFile(buf);
hdc = BeginPaint(hWnd, &ps);
if (gpPicture)
{
// get width and height of picture
long hmWidth;
long hmHeight;
gpPicture->get_Width(&hmWi
gpPicture->get_Height(&hmH
// convert himetric to pixels
int nWidth = MulDiv(hmWidth, GetDeviceCaps(hdc, LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, GetDeviceCaps(hdc, LOGPIXELSY), HIMETRIC_INCH);
RECT rc;
GetClientRect(hWnd, &rc);
// display picture using IPicture::Render
gpPicture->Render(hdc, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
}
EndPaint(hWnd, &ps);
i = i+1;
return DefWindowProc(hWnd, message, wParam, lParam);
}
whoa,,, basically you are trying to show a picture every few milliseconds (which is faster then the pic can be rendered),, or not at all depending on what your program is doing,, move your mouse over the apps window and TONS of mouse messages will be sent and you are trying to draw the picture each time.. like joghurt said you do that in WM_PAINT only,, and then have a way outside such as a timer to tell the window when to repaint.. every 300 milliseconds or something.
but the avi idea would be cleaner
but the avi idea would be cleaner
ASKER
joghurt thank 4 reply,
1. If you want a fast code then why are you drawing the image for every message? It would be enough to draw only for WM_PAINT messages.
How? Could you help me started in this? I'll try to look on line for sample code. C++ is not my native programming language.
2. I don't see any kind of timing. How do you want your frames (images) to be played with the same delay after each other?
Same delay would be fine. I just to make the frames in motion for now.
3. For me using IPicture::Render doesn't seem to be the fastest way to draw an image.
The reason I use it is b/c what MS loadpic use. I didn't know any other render method there are in C++.
I have no experience of doing avi stream. I'll do that next after I get the motion images with the JPEG file.
PlanetCpp
I'm still a novice in C++. I would love to see some sample code how render images using WM_PAINT. Could you help me? As I explained to joghurt, I use the rendering method based on what loadpic has .
1. If you want a fast code then why are you drawing the image for every message? It would be enough to draw only for WM_PAINT messages.
How? Could you help me started in this? I'll try to look on line for sample code. C++ is not my native programming language.
2. I don't see any kind of timing. How do you want your frames (images) to be played with the same delay after each other?
Same delay would be fine. I just to make the frames in motion for now.
3. For me using IPicture::Render doesn't seem to be the fastest way to draw an image.
The reason I use it is b/c what MS loadpic use. I didn't know any other render method there are in C++.
I have no experience of doing avi stream. I'll do that next after I get the motion images with the JPEG file.
PlanetCpp
I'm still a novice in C++. I would love to see some sample code how render images using WM_PAINT. Could you help me? As I explained to joghurt, I use the rendering method based on what loadpic has .
you can view my bitmap loading sample on my webiste www.PlanetCpp.com
if you are new to c++ i always suggest you learn the language well before you try to write gui's and if someone is new to writing gui's i always suggest they learn the basics before they get into graphic programming. you seemed to have jumped those two hurdles too soon.
graphics programming is VERY tricky at time expecially with GDI. your code may look lke it workes but still be riddled with memory leaks and potential crashes.
make sure you understand it first before you write it.
if you still want to get into it, lok at the bitmap loading example and also the timer example, you can time your frames then.
WM_PAINT is a message sent to your window when windows sees that it needs to be repainted, windows will take care of painting common classes and etc but you need to control the painting of anything else you wanted to add. you would add your code to load the image into the timer message or procedure,, then after its loaded you would tell window to repaint your window with updatewindow,, then wm_paint is where you paint the current frame
if you are new to c++ i always suggest you learn the language well before you try to write gui's and if someone is new to writing gui's i always suggest they learn the basics before they get into graphic programming. you seemed to have jumped those two hurdles too soon.
graphics programming is VERY tricky at time expecially with GDI. your code may look lke it workes but still be riddled with memory leaks and potential crashes.
make sure you understand it first before you write it.
if you still want to get into it, lok at the bitmap loading example and also the timer example, you can time your frames then.
WM_PAINT is a message sent to your window when windows sees that it needs to be repainted, windows will take care of painting common classes and etc but you need to control the painting of anything else you wanted to add. you would add your code to load the image into the timer message or procedure,, then after its loaded you would tell window to repaint your window with updatewindow,, then wm_paint is where you paint the current frame
ASKER
Thank, I'll try it out. I thought it would be easy to view jpeg in sequence.
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
2. I don't see any kind of timing. How do you want your frames (images) to be played with the same delay after each other?
3. For me using IPicture::Render doesn't seem to be the fastest way to draw an image.
All in all, why don't you convert your separate files into an AVI stream using the AviFile functions and play this stream?