// ImageViewerDlg.cpp : implementation file // #include "stdafx.h" #include "ImageViewer.h" #include "ImageViewerDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CImageViewerDlg dialog BYTE* bmpBuffer; BOOL bmpLoaded; JSAMPARRAY pBuffer; CImageViewerDlg::CImageViewerDlg(CWnd* pParent /*=NULL*/) : CDialog(CImageViewerDlg::IDD, pParent) { //{{AFX_DATA_INIT(CImageViewerDlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_InitDC = FALSE; m_txtFont.CreateFont(16,0,0,0,FW_NORMAL,0,0,0,GB2312_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,_T("Arial")); m_hBitmap = 0; m_SrcWidth = 0; m_SrcHeight = 0; m_SrcStartX = 0; m_SrcStartY = 0; m_FileNumber = 0; m_Zoom = 0; m_DelayTime = 1000 * 3; m_DefaultRect = CRect(59,37,262,209); m_DstStartX = m_DefaultRect.TopLeft().x; m_DstStartY = m_DefaultRect.TopLeft().y; m_DstWidth = m_DefaultRect.Width(); m_DstHeight = m_DefaultRect.Height(); m_WorkFileName = L"";//L"\\Storage Card\\Picturs\\jpg2.jpg"; // 初始化背景画刷 CBitmap tmpBmp; // 从资源中加载背景图片 tmpBmp.LoadBitmap(IDB_IMAGE_WND); m_BgDC.CreateCompatibleDC(NULL); m_BgDC.SelectObject(&tmpBmp); tmpBmp.DeleteObject(); m_bAutoPlay = false; m_bFullScreen = false; m_bReDraw = TRUE; } CImageViewerDlg::~CImageViewerDlg() { DeleteObject(m_hBitmap); m_BgDC.DeleteDC(); //m_MemDC.DeleteDC(); m_txtFont.DeleteObject(); m_DIBSection.DeleteObject(); } void CImageViewerDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CImageViewerDlg) DDX_Control(pDX, IDC_BUTTON_ZOOMOUT, m_butZoomOut); DDX_Control(pDX, IDC_BUTTON_OPEN, m_butOpen); DDX_Control(pDX, IDC_BUTTON_ZOOMIN, m_butZoomIn); DDX_Control(pDX, IDC_BUTTON_NEXT, m_butNext); DDX_Control(pDX, IDC_BUTTON_FULLSCREEN, m_butFullScreen); DDX_Control(pDX, IDC_BUTTON_CLOSE, m_butClose); DDX_Control(pDX, IDC_BUTTON_BACK, m_butBack); DDX_Control(pDX, IDC_BUTTON_AUTOPLAY, m_butAutoPlay); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CImageViewerDlg, CDialog) //{{AFX_MSG_MAP(CImageViewerDlg) ON_WM_PAINT() ON_WM_ERASEBKGND() ON_BN_CLICKED(IDC_BUTTON_AUTOPLAY, OnButtonAutoplay) ON_BN_CLICKED(IDC_BUTTON_BACK, OnButtonBack) ON_BN_CLICKED(IDC_BUTTON_CLOSE, OnButtonClose) ON_BN_CLICKED(IDC_BUTTON_FULLSCREEN, OnButtonFullscreen) ON_BN_CLICKED(IDC_BUTTON_NEXT, OnButtonNext) ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen) ON_BN_CLICKED(IDC_BUTTON_ZOOMIN, OnButtonZoomin) ON_BN_CLICKED(IDC_BUTTON_ZOOMOUT, OnButtonZoomout) ON_WM_LBUTTONDOWN() ON_WM_TIMER() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CImageViewerDlg message handlers BOOL CImageViewerDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon CenterWindow(GetDesktopWindow()); // center to the hpc screen // TODO: Add extra initialization here MoveWindow(0,0,320,240); // m_butZoomOut.MoveWindow(272,37,46,46); m_butZoomOut.LoadBitmaps(IDB_IMAGE_ZOOMOUT,IDB_IMAGE_ZOOMOUTD,IDB_IMAGE_ZOOMOUTDIS); m_butZoomIn.MoveWindow(272,87,46,46); m_butZoomIn.LoadBitmaps(IDB_IMAGE_ZOOMIN,IDB_IMAGE_ZOOMIND,IDB_IMAGE_ZOOMINDIS); m_butFullScreen.MoveWindow(272,137,46,46); m_butFullScreen.LoadBitmaps(IDB_IMAGE_FULLSCREEN,IDB_IMAGE_FULLSCREEND,IDB_IMAGE_FULLSCREENDIS); m_butAutoPlay.MoveWindow(272,187,46,46); m_butAutoPlay.LoadBitmaps(IDB_IMAGE_PLAY,IDB_IMAGE_PLAY,IDB_IMAGE_PLAYDIS); m_butBack.MoveWindow(1,56,46,46); m_butBack.LoadBitmaps(IDB_IMAGE_BACK,IDB_IMAGE_BACKD,IDB_IMAGE_BACKDIS); m_butNext.MoveWindow(1,113,46,46); m_butNext.LoadBitmaps(IDB_IMAGE_NEXT,IDB_IMAGE_NEXTD,IDB_IMAGE_NEXTDIS); m_butOpen.MoveWindow(1,170,46,46); m_butOpen.LoadBitmaps(IDB_IMAGE_OPEN,IDB_IMAGE_OPEND); m_butClose.MoveWindow(283,7,25,25); m_butClose.LoadBitmaps(IDB_IMAGE_CLOSE,IDB_IMAGE_CLOSED); //m_picImage.MoveWindow(59,37,203,172); //LoadImage(m_WorkFileName); return TRUE; // return TRUE unless you set the focus to a control } HBITMAP CImageViewerDlg::LoadImageJPG(const CString &strFileName) { FILE *pFile; JSAMPARRAY pBuffer; int nRowSize; ByteArray imageData(320 * 240 * 3); struct jpeg_error_mgr jerr; struct jpeg_decompress_struct cinfo; if((pFile = _tfopen(strFileName,_T("rb"))) == NULL) { CString strError; strError.Format(_T("Can't Open File '%s'"),strFileName); MessageBox(strError); return 0; } cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo,pFile); jpeg_read_header(&cinfo,TRUE); jpeg_start_decompress(&cinfo); nRowSize = cinfo.output_width * cinfo.output_components; pBuffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, nRowSize, 1); while(cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo,pBuffer,TRUE); imageData.Append(pBuffer[0],nRowSize); } m_SrcWidth = cinfo.output_width; m_SrcHeight = cinfo.output_height; if (m_hBitmap) { DeleteObject(m_hBitmap); } m_hBitmap = CSTScreenBuffer::CreateBitmapByRGBArray( imageData.GetData(),cinfo.output_width,cinfo.output_height); jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); fclose(pFile); return m_hBitmap; } void CImageViewerDlg::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here if (!m_WorkFileName.IsEmpty()) { CDC buffDC; CBitmap bgBmp; bgBmp.CreateCompatibleBitmap(&dc,320,240); buffDC.CreateCompatibleDC(&dc); buffDC.SelectObject(&bgBmp); if (m_bFullScreen) { m_DstHeight = 240; m_DstWidth = 320; m_DstStartX = m_DstStartY = 0; if (m_SrcHeight < m_DefaultRect.Height()) { m_DstHeight = m_SrcHeight; m_DstStartY = ((m_DefaultRect.Height() - m_SrcHeight) / 2) + m_DefaultRect.TopLeft().y; } if (m_SrcWidth < m_DefaultRect.Width()) { m_DstWidth = m_SrcWidth; m_DstStartX = ((m_DefaultRect.Width() - m_SrcWidth) / 2) + m_DefaultRect.TopLeft().x; } } else { buffDC.BitBlt(0,0,320,240,&m_BgDC,0,0,SRCCOPY); //dc.BitBlt(0,0,320,240,&m_BgDC,0,0,SRCCOPY); if (m_SrcHeight < m_DefaultRect.Height()) { m_DstHeight = m_SrcHeight; m_DstStartY = ((m_DefaultRect.Height() - m_SrcHeight) / 2) + m_DefaultRect.TopLeft().y; } else { m_DstHeight = m_DefaultRect.Height(); m_DstStartY = m_DefaultRect.TopLeft().y; } if (m_SrcWidth < m_DefaultRect.Width()) { m_DstWidth = m_SrcWidth; m_DstStartX = ((m_DefaultRect.Width() - m_SrcWidth) / 2) + m_DefaultRect.TopLeft().x; } else { m_DstWidth = m_DefaultRect.Width(); m_DstStartX = m_DefaultRect.TopLeft().x; } } if (m_hBitmap) { CDC m_MemDC; m_MemDC.CreateCompatibleDC(&dc); m_MemDC.SelectObject(m_hBitmap); if (!m_bFullScreen) { buffDC.FillSolidRect(&m_DefaultRect,RGB(0,0,0)); } else { buffDC.FillSolidRect(0,0,320,240,RGB(0,0,0)); } //buffDC.StretchBlt(m_DstStartX,m_DstStartY,m_DstWidth,m_DstHeight,&m_MemDC,m_SrcStartX,m_SrcStartY,m_SrcWidth,m_SrcHeight,SRCCOPY); buffDC.StretchBlt(m_DstStartX,m_DstStartY,m_DstWidth,m_DstHeight,&m_MemDC,(m_ImageSize.cx - m_SrcWidth)/2,(m_ImageSize.cy - m_SrcHeight)/2,m_SrcWidth,m_SrcHeight,SRCCOPY); buffDC.SetBkMode(TRANSPARENT); buffDC.SetTextColor(RGB(255,0,0)); buffDC.DrawText(GetFileName(m_WorkFileName),CRect(86,213,237,231),DT_CENTER|DT_VCENTER); dc.BitBlt(0,0,320,240,&buffDC,0,0,SRCCOPY); bgBmp.DeleteObject(); buffDC.DeleteDC(); m_MemDC.DeleteDC(); } } else { dc.BitBlt(0,0,320,240,&m_BgDC,0,0,SRCCOPY); } // Do not call CDialog::OnPaint() for painting messages } BOOL CImageViewerDlg::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default return TRUE; } void CImageViewerDlg::OnButtonAutoplay() { // TODO: Add your control notification handler code here m_bAutoPlay = !m_bAutoPlay; if (m_bAutoPlay) { Sleep(500); OnButtonNext(); SetTimer(1,m_DelayTime,NULL); m_butAutoPlay.LoadBitmaps(IDB_IMAGE_PLAYD,IDB_IMAGE_PLAYD,IDB_IMAGE_PLAYDIS); } else { KillTimer(1); m_butAutoPlay.LoadBitmaps(IDB_IMAGE_PLAY,IDB_IMAGE_PLAY,IDB_IMAGE_PLAYDIS); } m_butAutoPlay.Invalidate(); } void CImageViewerDlg::OnButtonBack() { // TODO: Add your control notification handler code here m_WorkFileName = g_Playlist.GetNextWorkFileName(TRUE,FALSE); LoadImage(m_WorkFileName); InvalidateRect(CRect(86,213,237,231)); Sleep(500); } void CImageViewerDlg::OnButtonClose() { // TODO: Add your control notification handler code here EndDialog(IDOK); } void CImageViewerDlg::OnButtonFullscreen() { // TODO: Add your control notification handler code here if (!m_bFullScreen) { ShowControl(FALSE); m_SrcHeight = m_ImageSize.cy; m_SrcWidth = m_ImageSize.cx; m_SrcStartX = 0; m_SrcStartY = 0; m_Zoom = 0; m_bFullScreen = TRUE; Invalidate(); } } void CImageViewerDlg::OnButtonNext() { // TODO: Add your control notification handler code here m_WorkFileName = g_Playlist.GetNextWorkFileName(FALSE,FALSE); LoadImage(m_WorkFileName); InvalidateRect(CRect(86,213,237,231)); Sleep(500); } void CImageViewerDlg::OnButtonOpen() { // TODO: Add your control notification handler code here COpenImageFileDlg dlg; if (dlg.DoModal() == IDOK) { if (g_Playlist.m_TotalFiles > 1) { m_butNext.EnableWindow(TRUE); m_butBack.EnableWindow(TRUE); m_butAutoPlay.EnableWindow(TRUE); m_WorkFileName = g_Playlist.m_FilePath + g_Playlist.m_FileList.GetAt(g_Playlist.m_CurrentFile); m_FileNumber = g_Playlist.m_TotalFiles; } else { m_butNext.EnableWindow(FALSE); m_butBack.EnableWindow(FALSE); m_butAutoPlay.EnableWindow(FALSE); m_WorkFileName = dlg.GetFilePath(); m_FileNumber = 1; } if (!m_WorkFileName.IsEmpty()) { m_butZoomIn.EnableWindow(TRUE); m_butZoomOut.EnableWindow(TRUE); m_butFullScreen.EnableWindow(TRUE); if (m_FileNumber > 1) { m_butBack.EnableWindow(TRUE); m_butNext.EnableWindow(TRUE); } else { m_butBack.EnableWindow(FALSE); m_butNext.EnableWindow(FALSE); } } else { m_butZoomIn.EnableWindow(FALSE); m_butZoomOut.EnableWindow(FALSE); m_butAutoPlay.EnableWindow(FALSE); m_butFullScreen.EnableWindow(FALSE); m_butBack.EnableWindow(FALSE); m_butNext.EnableWindow(FALSE); } LoadImage(m_WorkFileName); } } void CImageViewerDlg::OnButtonZoomin() { // TODO: Add your control notification handler code here if (m_Zoom > 0) { if (m_ZoomQuotiety > 0) { ZoomImage(--m_Zoom); InvalidateRect(m_DefaultRect); } } } void CImageViewerDlg::OnButtonZoomout() { // TODO: Add your control notification handler code here if (m_Zoom < MAX_ZOOM) { if (m_ZoomQuotiety > 0) { ZoomImage(++m_Zoom); InvalidateRect(m_DefaultRect); } } } bool CImageViewerDlg::LoadImage(CString strFileName) { // return TRUE; CClientDC dc(this); switch(GetImageType(strFileName)) { case IMG_BMP: // 装载Bitmap格式的图片 //m_hBitmap = SHLoadDIBitmap(strFileName); if (m_hBitmap) { DeleteObject(m_hBitmap); m_hBitmap = NULL; m_DIBSection.DeleteObject(); } m_DIBSection.Load(strFileName); m_hBitmap = m_DIBSection.GetSafeHandle(); if (!m_hBitmap) { return FALSE; }else { // 获取图片宽和高 m_SrcWidth = m_DIBSection.GetWidth(); m_SrcHeight = m_DIBSection.GetHeight(); m_ImageSize = CSize(m_SrcWidth,m_SrcHeight); } break; case IMG_JPG: if (m_hBitmap) { DeleteObject(m_hBitmap); m_hBitmap = NULL; } LoadImageJPG(strFileName); if(!m_hBitmap) { return false; } else { m_ImageSize = CSize(m_SrcWidth,m_SrcHeight); } break; case IMG_UNKNOWN: m_hBitmap = NULL; //MessageBox(L"该图片格式暂不支持...."); return FALSE; break; } if (m_DstHeight != 0 && m_DstWidth != 0 && m_SrcHeight != 0 && m_SrcWidth != 0) { m_ZoomQuotiety = (m_SrcWidth - m_DefaultRect.Width()) / (MAX_ZOOM + 1); } else { m_ZoomQuotiety = 0; } if (m_bFullScreen) { Invalidate(); } else { InvalidateRect(m_DefaultRect); } return true; } int CImageViewerDlg::GetImageType(CString strFileName) { // 判断文件是否是Bitmap位图 CFile file; CFileException e; // 打开文件 file.Open(strFileName,CFile::modeRead,&e); // 读取文件前两个字节 BYTE bBuffer[2]; file.Read(bBuffer,2); file.Close(); // 判断前两个字节是不是'BM' if (bBuffer[0] == 0x42 && bBuffer[1] == 0x4D) { return IMG_BMP; } else { if (bBuffer[0] == 0xFF && bBuffer[1] == 0xD8) { return IMG_JPG; } } return IMG_UNKNOWN; } void CImageViewerDlg::ZoomImage(int iZoom) { if (iZoom == 0) { m_SrcHeight = m_ImageSize.cy; m_SrcWidth = m_ImageSize.cx; m_SrcStartX = m_SrcStartY = 0; } else if(iZoom != MAX_ZOOM) { int tmpQuotiety = iZoom * m_ZoomQuotiety; if(m_ImageSize.cx < m_DefaultRect.Width() && m_ImageSize.cy < m_DefaultRect.Height()) { m_SrcWidth = m_ImageSize.cx + tmpQuotiety; m_SrcHeight = m_ImageSize.cy + tmpQuotiety; } else { if (m_ImageSize.cx < m_DefaultRect.Width()) { m_SrcWidth = m_ImageSize.cx + tmpQuotiety; } else { m_SrcWidth = (m_ImageSize.cx - tmpQuotiety); } if (m_ImageSize.cy < m_DefaultRect.Height()) { m_SrcHeight = m_ImageSize.cy + tmpQuotiety; } else { m_SrcHeight = (m_ImageSize.cy - tmpQuotiety); } } } else { if(m_ImageSize.cx < m_DefaultRect.Width() && m_ImageSize.cy < m_DefaultRect.Height()) { m_SrcWidth = m_ImageSize.cx; m_SrcHeight = m_ImageSize.cy; m_SrcStartX = m_SrcStartY = 0; } else { if (m_ImageSize.cx < m_DefaultRect.Width()) { m_SrcWidth = m_ImageSize.cx; } else { m_SrcWidth = m_DefaultRect.Width(); } if (m_ImageSize.cy < 200) { m_SrcHeight = m_ImageSize.cy; } else { m_SrcHeight = m_DefaultRect.Height(); } } } } void CImageViewerDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if (m_butFullScreen) { // if (m_bAutoPlay) // { // m_bAutoPlay = FALSE; // m_butAutoPlay.LoadBitmaps(IDB_IMAGE_PLAY,IDB_IMAGE_PLAYD,IDB_IMAGE_PLAYDIS); // m_butAutoPlay.Invalidate(); // KillTimer(1); // } m_DstStartX = m_DefaultRect.TopLeft().x; m_DstStartY = m_DefaultRect.TopLeft().y; m_DstWidth = m_DefaultRect.Width(); m_DstHeight = m_DefaultRect.Height(); m_bFullScreen = FALSE; Invalidate(); ShowControl(TRUE); } CDialog::OnLButtonDown(nFlags, point); } void CImageViewerDlg::ShowControl(BOOL bShow) { if (bShow) { m_butZoomIn.ShowWindow(SW_SHOW); m_butZoomOut.ShowWindow(SW_SHOW); m_butAutoPlay.ShowWindow(SW_SHOW); m_butFullScreen.ShowWindow(SW_SHOW); m_butBack.ShowWindow(SW_SHOW); m_butNext.ShowWindow(SW_SHOW); m_butClose.ShowWindow(SW_SHOW); m_butOpen.ShowWindow(SW_SHOW); } else { m_butZoomIn.ShowWindow(SW_HIDE); m_butZoomOut.ShowWindow(SW_HIDE); m_butAutoPlay.ShowWindow(SW_HIDE); m_butFullScreen.ShowWindow(SW_HIDE); m_butBack.ShowWindow(SW_HIDE); m_butNext.ShowWindow(SW_HIDE); m_butClose.ShowWindow(SW_HIDE); m_butOpen.ShowWindow(SW_HIDE); } } CString CImageViewerDlg::GetFileName(CString strFileName) { CString FileExt; FileExt.Empty(); // 文件名长度 int strLen = strFileName.GetLength() - 1; for(int i = strLen; i >= 0; i--) { // 查找文件名中最好一个'.' if(strFileName.GetAt(i) == '\\') { // 提取文件扩展名 FileExt = strFileName.Right(strLen - i); break; } } strLen = FileExt.GetLength() - 1; strFileName = FileExt; for(i = strLen; i >= 0; i--) { // 查找文件名中最好一个'.' if(strFileName.GetAt(i) == '.') { // 提取文件扩展名 FileExt = strFileName.Left(i); break; } } return FileExt; } void CImageViewerDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default OnButtonNext(); CDialog::OnTimer(nIDEvent); } CRect CImageViewerDlg::GetZoomRect(CRect *rcScreen, CSize sizePicture) { CRect rect(rcScreen); double dWidth = rcScreen->Width(); double dHeight = rcScreen->Height(); double dAspectRatio = dWidth/dHeight; double dPictureWidth = sizePicture.cx; double dPictureHeight = sizePicture.cy; double dPictureAspectRatio = dPictureWidth/dPictureHeight; //If the aspect ratios are the same then the screen rectangle // will do, otherwise we need to calculate the new rectangle if (dPictureAspectRatio > dAspectRatio) { int nNewHeight = (int)(dWidth/dPictureWidth*dPictureHeight); int nCenteringFactor = (rcScreen->Height() - nNewHeight) / 2; rect.SetRect( 0, nCenteringFactor, (int)dWidth, nNewHeight + nCenteringFactor); } else if (dPictureAspectRatio < dAspectRatio) { int nNewWidth = (int)(dHeight/dPictureHeight*dPictureWidth); int nCenteringFactor = (rcScreen->Width() - nNewWidth) / 2; rect.SetRect( nCenteringFactor, 0, nNewWidth + nCenteringFactor, (int)(dHeight)); } return rect; }