I'm developing an MFC doc-view based Image viewer application. The viewer have option for zooming & panning image.
For displaying the image I'm using stretchBlt GDI function.
StretchBlt(
int x,
int y,
int nWidth,
int nHeight,
CDC* pSrcDC,
int xSrc,
int ySrc,
int nSrcWidth,
int nSrcHeight,
DWORD dwRop
);
The destination stretch window size for StretchBlt is calculating based on Image aspect ratio (nSrcWidth / nSrcHeight) and window aspect ratio. And the image is placed on the center of the
window.
I implemented zoom functionality by varying the destination stretch window size(nWidth x nHeight) based on the zoom factor(by multiplying both width & height values with zoom factor).
Also panning is implemented by shifting destination stretch window start points(x & y) values based on pan shift values(by adding corresponding pan height & width values to x & y).
And I'm keeping xSrc & ySrc values as 0 and nSrcWidth and nSrcHeight value as such of the original image.
The image viewer and zoom and pan operations are working properly.
My actual problems I need to implement zooming based on a point in displaying image.
If I zoom select a point on the image by clicking in corresponding displaying window point, after zooming the same image pixel (in zoomed image)should be displayed in same window point.
How would I can implement this?
Below is an abstract of my code
CMyView:: OnDraw(CDC pDC)
{
CRect rcClient(0, 0, 0, 0);
GetClientRect(rcClient);
m_ImagActSize = pDoc->GetImageSize();
// m_ImageSize is CSize global member of my class which contain actual size of image.
const int cx = rcClient.right; // view client area width
const int cy = rcClient.bottom; // view client area height
const int bx = m_ImagActSize.cx; // source bitmap stretch width
const int by = m_ImagActSize.cy; // source bitmap stretch height
const int vx = (int)(bx * m_fZoom * m_pdnXMapRatio);
// vx:- virtual document width
// m_fZoom : which will vary with selected zoom operation
//m_pdnXMapRatio : This value is a factor (width) which is calculated based on aspect ratio of image and clent area. This is used to maintaion aspect ration of image in window.
const int vy = (int)(by * m_fZoom * m_pdnYMapRatio);
xDtn = m_xShift + m_xPanValue;
yDtn = m_yShift + m_yPanValue;
//m_xShift : a constant width shift value which is for centering the image in client window.
//m_yShift : a constant height shift value which is for centering the image in client window.
//m_xPanValue & m_yPanValue : width & height pan value which will be varied in pan operation.
// vy:- virtual document height
// m_fZoom : which will vary with selected zoom operation
//m_pdnYMapRatio : This value is a factor(height) which is calculated based on aspect ratio of image and clent area. This is used to maintaion aspect ration of image in window.
CImage& Image = pDoc->GetImage();
pDC->SetStretchBltMode(COLORONCOLOR);
Image.StretchBlt(pDC->GetSafeHdc(), xDtn, yDtn, vx, vy, 0, 0, bx, by, SRCCOPY);
}
I think ,this can be achieved by varying Dest window start values(x & y) based on the zoom .
For this I need to know
how stretchBlt function Stretches or Shrink the image based on sizes of image & displaying screen window?
how could exactly calculate how much the window start points should be shifted(while zoom) to correlate the relation between image pixel & window pixel?
Can anyone support to solve this issue?