📄 imageview.cpp
字号:
// ImageView.cpp : implementation of the CImageView class
//
#include "stdafx.h"
#include "Image.h"
#include "ImageDoc.h"
#include "ImageView.h"
#include "ByteArray.h"
#include "JpegWriter.h"
extern "C" {
#include "../JpegLib/jpeglib.h"
}
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CImageView
JSAMPARRAY pBuffer;
int nRowSize;
BYTE* bmpBuffer;
BOOL bmpLoaded;
IMPLEMENT_DYNCREATE(CImageView, CScrollView)
BEGIN_MESSAGE_MAP(CImageView, CScrollView)
//{{AFX_MSG_MAP(CImageView)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
ON_COMMAND(ID_PROCESS_NEGATIVE, OnProcessNegative)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CImageView construction/destruction
CImageView::CImageView()
{
// TODO: add construction code here
m_hBitmap=0;
Width=Height=0;
bmpLoaded=FALSE;
}
CImageView::~CImageView()
{
}
BOOL CImageView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CImageView drawing
void CImageView::OnDraw(CDC* pDC)
{
CImageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
LeftTop=GetScrollPosition();
CPaintDC dc(this);
if (m_hBitmap)
{
CDC memDc;
VERIFY(memDc.CreateCompatibleDC(&dc));
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(memDc.GetSafeHdc(), m_hBitmap);
VERIFY(dc.BitBlt(-LeftTop.x, -LeftTop.y, Width, Height, &memDc, 0, 0, SRCCOPY));
::SelectObject(memDc.GetSafeHdc(), hOldBitmap);
VERIFY( memDc.DeleteDC() );
}
}
void CImageView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
}
/////////////////////////////////////////////////////////////////////////////
// CImageView diagnostics
#ifdef _DEBUG
void CImageView::AssertValid() const
{
CScrollView::AssertValid();
}
void CImageView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CImageDoc* CImageView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImageDoc)));
return (CImageDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CImageView message handlers
void CImageView::OnFileOpen()
{
CString FileName(_T(""));
CFileDialog FileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,TEXT("JPEG Files(*.JPG)|*.JPG||"));
if(FileDlg.DoModal()==IDOK)
{
FileName=FileDlg.GetPathName();
}
if(FileName!="")
{
LoadImage(FileName);
}
if(!m_hBitmap)
{
return;
}
CSize sizeTotal;
sizeTotal.cx = Width;
sizeTotal.cy = Height;
SetScrollSizes(MM_TEXT, sizeTotal);
LeftTop.x=LeftTop.y=0;
ScrollToPosition(LeftTop);
Invalidate();
}
void CImageView::OnFileSaveAs()
{
CString FileName(_T(""));
CFileDialog FileDlg(FALSE,NULL,NULL,OFN_HIDEREADONLY,TEXT("JPEG Files(*.JPG)|*.JPG||"));
if(FileDlg.DoModal()==IDOK)
{
FileName=FileDlg.GetPathName();
}
if(m_hBitmap)
{
SaveImage(FileName);
}
else
{
AfxMessageBox(_T("请先打开文件!"));
}
}
void CImageView::LoadImage(const CString &strFileName)
{
FILE * pFile;
struct jpeg_error_mgr jerr;
struct jpeg_decompress_struct cinfo;
int i,start;
start=0;
if ((pFile = _tfopen(strFileName, _T("rb"))) == NULL) {
CString strError;
strError.Format(_T("无法打开文件 '%s'"), strFileName);
AfxMessageBox(strError);
}
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;
Width=cinfo.output_width;
Height=cinfo.output_height;
if(bmpLoaded)
{
delete bmpBuffer;
}
bmpBuffer=new BYTE[(Height+1)*Width*3];
bmpLoaded=TRUE;
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, 1);
start=nRowSize*cinfo.output_scanline;
for(i=0;i<nRowSize;i++)
{
bmpBuffer[start+i]=pBuffer[0][i];
}
}
CreateBitmap();
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(pFile);
}
void CImageView::SaveImage(const CString &strFileName)
{
int nQuality=85;
//if(! ::WriteBitmapIntoJpegFile(strFileName, nQuality, m_hBitmap))
if(!::WriteRGBBytesIntoJpegFile(strFileName,Width,Height,nQuality,bmpBuffer))
{
::AfxMessageBox(GetJpegWriterError());
}
}
void CImageView::CreateBitmap()
{
int m_nCorrectedWidth,m_nWidth,m_nHeight;
m_nCorrectedWidth = ( ( Width + 3 ) / 4 ) * 4;
m_nWidth = Width;
m_nHeight = Height;
DIBINFO dibInfo;
BGRColor *m_pBuffer;
dibInfo.bmiHeader.biBitCount = 24;
dibInfo.bmiHeader.biClrImportant = 0;
dibInfo.bmiHeader.biClrUsed = 0;
dibInfo.bmiHeader.biCompression = 0;
dibInfo.bmiHeader.biHeight = m_nHeight;
dibInfo.bmiHeader.biPlanes = 1;
dibInfo.bmiHeader.biSize = 40;
dibInfo.bmiHeader.biSizeImage = m_nCorrectedWidth*m_nHeight*3;
dibInfo.bmiHeader.biWidth = m_nCorrectedWidth;
dibInfo.bmiHeader.biXPelsPerMeter = 3780;
dibInfo.bmiHeader.biYPelsPerMeter = 3780;
dibInfo.bmiColors[0].rgbBlue = 0;
dibInfo.bmiColors[0].rgbGreen = 0;
dibInfo.bmiColors[0].rgbRed = 0;
dibInfo.bmiColors[0].rgbReserved = 0;
HDC hDC = ::GetDC(NULL);
if(m_hBitmap)
{
::DeleteObject(m_hBitmap);
m_hBitmap=0;
}
m_hBitmap = CreateDIBSection(hDC, (const BITMAPINFO*)dibInfo, DIB_RGB_COLORS, (void**)&m_pBuffer, NULL, 0);
::ReleaseDC(NULL,hDC);
int nPosition = 0;
int nDataPosition = 0;
for (int y=0; y<Height; y++) {
nPosition = m_nCorrectedWidth*(m_nHeight-y-1);
nDataPosition = Width*3*y;
for (int x=0; x<Width; x++) {
m_pBuffer[nPosition].m_R = bmpBuffer[nDataPosition++];
m_pBuffer[nPosition].m_G = bmpBuffer[nDataPosition++];
m_pBuffer[nPosition].m_B = bmpBuffer[nDataPosition++];
nPosition++;
}
}
}
void CImageView::ProcessNegative()
{
int i;
for(i=0;i<Width*Height*3;i++)
{
bmpBuffer[i]=255-bmpBuffer[i];
}
CreateBitmap();
}
void CImageView::OnProcessNegative()
{
if(!m_hBitmap)
{
return;
}
ProcessNegative();
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -