jpegcodedlg.cpp
来自「《Visual C++视频技术方案宝典》配套光盘」· C++ 代码 · 共 1,095 行 · 第 1/2 页
CPP
1,095 行
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CJpegCodeDlg dialog
CJpegCodeDlg::CJpegCodeDlg(CWnd* pParent /*=NULL*/)
: CDialog(CJpegCodeDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CJpegCodeDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
m_hBmp = NULL;
m_Name = "";
}
void CJpegCodeDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CJpegCodeDlg)
DDX_Control(pDX, IDC_BKDEMO, m_Demo);
DDX_Control(pDX, IDC_FILENAME, m_FileName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CJpegCodeDlg, CDialog)
//{{AFX_MSG_MAP(CJpegCodeDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BROWN, OnBrown)
ON_BN_CLICKED(IDC_JPEGSAVE, OnJpegSave)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CJpegCodeDlg message handlers
BOOL CJpegCodeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 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
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CJpegCodeDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CJpegCodeDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
if (m_hBmp != NULL)
{
CDC* pDC = m_Demo.GetDC();
CBitmap bmp;
bmp.Attach(m_hBmp);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&bmp);
CRect rc;
m_Demo.GetClientRect(rc);
BITMAP bInfo;
bmp.GetBitmap(&bInfo);
int x = bInfo.bmWidth;
int y = bInfo.bmHeight;
pDC->StretchBlt(0,0,rc.Width(),rc.Height(),&memDC,0,0,x,y,SRCCOPY);
pDC->DeleteDC();
bmp.DeleteObject();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CJpegCodeDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CJpegCodeDlg::OnOK()
{
CString fName;
m_FileName.GetWindowText(fName);
if (! fName.IsEmpty())
{
m_Name = fName;
m_hBmp = (HBITMAP)::LoadImage(NULL,fName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTSIZE);
}
else
{
m_Name = "";
m_hBmp = NULL;
}
OnPaint();
}
void CJpegCodeDlg::OnBrown()
{
CFileDialog fDlg(TRUE,"","",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"位图文件(bmp)|*.bmp");
if (fDlg.DoModal()==IDOK)
{
m_FileName.SetWindowText(fDlg.GetPathName());
}
}
void CJpegCodeDlg::OnJpegSave()
{
CFileDialog fDlg(false,"jpeg","mrkj",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"JPEG文件|(*.jpeg;*.jpg)");
if (fDlg.DoModal()==IDOK)
{
CString strFileName = fDlg.GetPathName();
SaveJpeg(NULL,strFileName,24,80);
}
}
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
void CJpegCodeDlg::SaveJpeg(unsigned char *pBitdata, LPCSTR lpstrFileName, BOOL bColor, int Quality)
{
CFile file;
file.Open(m_Name,CFile::modeReadWrite);
DWORD len = file.GetLength();
BITMAPFILEHEADER bmpFileheader;
file.Read(&bmpFileheader,sizeof(BITMAPFILEHEADER));
unsigned char* pBuffer = new unsigned char[len];
memset(pBuffer,0,len);
file.ReadHuge(pBuffer,len);
file.Close();
BITMAPINFOHEADER bmpHeader;
memcpy(&bmpHeader,pBuffer,sizeof(BITMAPINFOHEADER));
//获取图像的高度和宽度
int bmpHeight = bmpHeader.biHeight;
int bmpWidth = bmpHeader.biWidth;
int cnt = bmpHeader.biBitCount;
unsigned char* newBuffer = NULL;
//如果不是24色的位图,需要进行转换
if (cnt != 24)
newBuffer = ConvertBmpFormat(pBuffer,24,bmpHeader.biSizeImage,bmpWidth,bmpHeight);
BYTE* pTemp ;
if (newBuffer != NULL)
pTemp = newBuffer;
else
pTemp = pBuffer;
pTemp+= 40;
BYTE* tmp = CancelAlign((BYTE*)pTemp,
bmpWidth,
WIDTHBYTES(bmpWidth * 24),
bmpHeight);
FlipBuf(tmp, bmpWidth*3, bmpHeight);
ConvertRGB(tmp, bmpWidth, bmpHeight);
BOOL bSuccess = WriteJPEGFile(lpstrFileName,
tmp,
bmpWidth,
bmpHeight,
bColor,
Quality);
delete pBuffer;
}
//转换为24色位图
unsigned char* CJpegCodeDlg::ConvertBmpFormat(unsigned char *pDib, int Colors, DWORD dwImageSize,int Width,int Height)
{
LPBITMAPINFO lpbmi = NULL;
LPBYTE lpSourceBits, lpTargetBits, lpResult;
HDC hDC = NULL, hSourceDC, hTargetDC;
HBITMAP hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap;
DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize, dwColorNum;
HANDLE hNewDIB;
DWORD dwSize;
if (Colors<= 8)
dwColorNum = 1 << Colors;
else
dwColorNum = 0;
dwTargetHeaderSize = sizeof( BITMAPINFO ) + ( dwColorNum * sizeof( RGBQUAD ) );
LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)pDib;
lpbmi = (LPBITMAPINFO)malloc( dwTargetHeaderSize );
lpbmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
lpbmi->bmiHeader.biWidth = Width;
lpbmi->bmiHeader.biHeight = Height;
lpbmi->bmiHeader.biPlanes = 1;
lpbmi->bmiHeader.biBitCount = Colors;
lpbmi->bmiHeader.biCompression = BI_RGB;
lpbmi->bmiHeader.biSizeImage = 0;
lpbmi->bmiHeader.biXPelsPerMeter = 0;
lpbmi->bmiHeader.biYPelsPerMeter = 0;
lpbmi->bmiHeader.biClrUsed = 0;
lpbmi->bmiHeader.biClrImportant = 0;
HPALETTE hPalSrc;
if( ! CopyColorTable( lpbmi, (LPBITMAPINFO)lpSrcDIB, NULL) )
{
free( lpbmi );
return NULL;
}
hDC = ::GetDC(NULL );
hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS, (VOID **)&lpTargetBits, NULL, 0 );
hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS, (VOID **)&lpSourceBits, NULL, 0 );
hSourceDC = CreateCompatibleDC( hDC );
hTargetDC = CreateCompatibleDC( hDC );
dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader));
dwTargetBitsSize = lpbmi->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpbmi->bmiHeader));
memcpy( lpSourceBits, FindDIBBits((char*)pDib), dwSourceBitsSize );
lpbmi->bmiHeader.biSizeImage = dwTargetBitsSize;
hOldSourceBitmap = (HBITMAP)SelectObject( hSourceDC, hSourceBitmap );
hOldTargetBitmap = (HBITMAP)SelectObject( hTargetDC, hTargetBitmap );
if( lpSrcDIB->bmiHeader.biBitCount <= 8 )
SetDIBColorTable( hSourceDC, 0, 1 << lpSrcDIB->bmiHeader.biBitCount, lpSrcDIB->bmiColors );
if( lpbmi->bmiHeader.biBitCount <= 8 )
SetDIBColorTable( hTargetDC, 0, 1 << lpbmi->bmiHeader.biBitCount, lpbmi->bmiColors );
BitBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY );
SelectObject( hSourceDC, hOldSourceBitmap );
SelectObject( hTargetDC, hOldTargetBitmap );
DeleteDC( hSourceDC );
DeleteDC( hTargetDC );
::ReleaseDC( NULL,hDC );
GdiFlush();
dwSize = dwTargetHeaderSize + dwTargetBitsSize;
hNewDIB = GlobalAlloc(GHND, dwSize);
lpResult = (LPBYTE)GlobalLock(hNewDIB);
memcpy( lpResult, lpbmi, dwTargetHeaderSize );
memcpy( FindDIBBits( (char*)lpResult ), lpTargetBits, dwTargetBitsSize );
DeleteObject( hTargetBitmap );
DeleteObject( hSourceBitmap );
free( lpbmi );
return lpResult;
}
unsigned char* CJpegCodeDlg::CancelAlign(unsigned char * pBuf, UINT wPix, UINT wBytes, UINT Height)
{
unsigned char *tmp;
tmp=new unsigned char [Height * wPix * 3];
if (tmp==NULL)
return NULL;
for (int i=0 ; i <Height; i++)
{
memcpy((tmp+i * wPix * 3),
(pBuf + i * wBytes),
wPix * 3);
}
return tmp;
}
BOOL CJpegCodeDlg::FlipBuf(unsigned char *pInbuf, UINT WidthBytes, UINT Height)
{
unsigned char *pChar1;
unsigned char *pChar2;
if (pInbuf==NULL)
return FALSE;
UINT size = WidthBytes;
pChar1 = new unsigned char [size];
if (pChar1==NULL)
{
return FALSE;
}
pChar2 = new unsigned char [size];
if (pChar2==NULL)
{
return FALSE;
}
ULONG off1=0;
ULONG off2=0;
for (int row=0;row <(Height+1)/2; row++)
{
off1=row*size;
off2=((Height-1)-row)*size;
memcpy(pChar1,pInbuf+off1,size);
memcpy(pChar2,pInbuf+off2,size);
memcpy(pInbuf+off1,pChar2,size);
memcpy(pInbuf+off2,pChar1,size);
}
delete [] pChar1;
delete [] pChar2;
return TRUE;
}
void CJpegCodeDlg::ConvertRGB(unsigned char *pBuf, UINT Width, UINT Height)
{
UINT col, row;
for ( row=0 ; row<Height ; row++)
{
for (col=0; col<Width; col++)
{
unsigned char* pRed, *pGrn, *pBlu;
pRed = pBuf + row * Width * 3 + col * 3;
pGrn = pBuf + row * Width * 3 + col * 3 + 1;
pBlu = pBuf + row * Width * 3 + col * 3 + 2;
unsigned char unChar;
unChar = *pRed;
*pRed = *pBlu;
*pBlu = unChar;
}
}
}
BOOL CJpegCodeDlg::WriteJPEGFile(LPCSTR lpstrFileName, BYTE *dataBuf, UINT widthPix, UINT height, BOOL color, int quality)
{
if (dataBuf==NULL)
return FALSE;
if (widthPix==0)
return FALSE;
if (height==0)
return FALSE;
LPBYTE tmp;
if (!color)
{
tmp = (BYTE*)new BYTE[widthPix*height];
if (tmp==NULL)
{
return FALSE;
}
UINT row,col;
for (row=0;row<height;row++)
{
for (col=0;col<widthPix;col++)
{
LPBYTE pRed, pGrn, pBlu;
pRed = dataBuf + row * widthPix * 3 + col * 3;
pGrn = dataBuf + row * widthPix * 3 + col * 3 + 1;
pBlu = dataBuf + row * widthPix * 3 + col * 3 + 2;
// 计算图像亮度值
int lum = (int)(.299 * (double)(*pRed) + .587 * (double)(*pGrn) + .114 * (double)(*pBlu));
LPBYTE pGray;
pGray = tmp + row * widthPix + col;
*pGray = (BYTE)lum;
}
}
}
//定义压缩信息
struct jpeg_compress_struct cinfo;
//定义缓冲区
FILE * outfile;
int row_stride;
//定义错误信息
struct jpeg_error_mgr jerr;
//为JPEG文件压缩对象分配内存并对其初始化
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
//打开文件并设定数据目标
if ((outfile = fopen(lpstrFileName, "wb")) == NULL)
{
return FALSE;
}
jpeg_stdio_dest(&cinfo, outfile);
//设置压缩参数
cinfo.image_width = widthPix;
cinfo.image_height = height;
if (color)
{
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
}
else
{
cinfo.input_components = 1;
cinfo.in_color_space = JCS_GRAYSCALE;
}
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE );
//开始压缩
jpeg_start_compress(&cinfo, TRUE);
//写入扫描线
row_stride = widthPix * 3;
while (cinfo.next_scanline < cinfo.image_height)
{
LPBYTE outRow;
if (color)
{
outRow = dataBuf + (cinfo.next_scanline * widthPix * 3);
}
else
{
outRow = tmp + (cinfo.next_scanline * widthPix);
}
(void) jpeg_write_scanlines(&cinfo, &outRow, 1);
}
//完成压缩
jpeg_finish_compress(&cinfo);
fclose(outfile);
//释放压缩对象
jpeg_destroy_compress(&cinfo);
if (!color)
delete [] tmp;
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?