⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfcview.cpp

📁 jpeg压缩
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		Invalidate(TRUE);
	}
}

////////////////////////////////////////////////////////////////////////////
//
//	save an 8-bit GIF from our 24-bit global buffer. this requires color
//	quantization of some kind.

void CMfcappView::SaveGIF(CString filename)
{
	// note, because i'm lazy, most image data in this app
	// is handled as 24-bit images. this makes the DIB
	// conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
	// significantly more difficult to handle.

	if (m_buf==NULL) {
		AfxMessageBox("No Image!");
		return;
	}

	// get quantization params
	CQuantDlg theDlg;
	if (theDlg.DoModal()!=IDOK) {
		return;
	}

	// convert from DIB orientation
	JpegFile::VertFlipBuf(m_buf, m_width * 3, m_height);

	// swap red and blue
	JpegFile::BGRFromRGB(m_buf, m_width, m_height);

	///////////////////////////////////////////////////////////////
	// color quantization section - make an 8-bit image that looks like
	// our 24-bit image...

	// the palette
	RGBQUAD RGBpal[256];
	
	BYTE *colormappedBuffer;

	// color or gray?
	if (theDlg.m_color) {
		// color !

		// allocate a buffer to colormap to
		colormappedBuffer = (BYTE *)  new BYTE[m_width* m_height];
		if (colormappedBuffer==NULL) {
			AfxMessageBox("Alloc error in SaveGIF!");
			return ;
		}

		BYTE tmpPal[3][256];
		// colormap it 
		if (!dl1quant(m_buf,						// input
							colormappedBuffer,		// output
							m_width,
							m_height,
							theDlg.m_quantColors,
							TRUE,
							tmpPal)) {
			AfxMessageBox("Quantization error");
			delete [] colormappedBuffer;
			return;
		}

		// copy our palette
		for (UINT col=0;col<256;col++) {
			if (col>theDlg.m_quantColors) {
				RGBpal[col].rgbRed=0;
				RGBpal[col].rgbBlue=0;
				RGBpal[col].rgbGreen=0;
			} else {
				RGBpal[col].rgbRed=tmpPal[0][col];
				RGBpal[col].rgbGreen=tmpPal[1][col];
				RGBpal[col].rgbBlue=tmpPal[2][col];
			}
		}
	} else {
		// convert to 8-bit grayscale
		colormappedBuffer = MakeColormappedGrayscale(m_buf,					// RGB
													(UINT)m_width,			// pixels
													(UINT)m_height, 
													(UINT)m_width * 3,		// bytes
													(UINT)256,				// colors
													RGBpal);				// palette

	}

	if (colormappedBuffer==NULL) {
		AfxMessageBox("Failed to make 256 color image");
		return;
	}

	// figure out the palette entries
	int red[256], blue[256], green[256];
	for (int i=0;i<256;i++) {
		red[i]	=	RGBpal[i].rgbRed;
		green[i]=	RGBpal[i].rgbGreen;
		blue[i]	=	RGBpal[i].rgbBlue;
	}

	// write it
	GIFFile theGifThing;
	if (!theGifThing.GIFWriteFileFrom256Color(colormappedBuffer,
												filename,
												m_width, 
												m_height,
												0,					// background color
												red, green, blue)) {

		AfxMessageBox(theGifThing.m_GIFErrorText);
	} else {
		// load what we just saved
		LoadGIF(filename);
		Invalidate(TRUE);
	}


	if (colormappedBuffer!=NULL)
		delete [] colormappedBuffer;

}

////////////////////////////////////////////////////////////////////////////
//
//	use the BMPFile class to write a 24-bit BMP file
//

void CMfcappView::SaveBMP24(CString filename)
{
	// note, because i'm lazy, most image data in this app
	// is handled as 24-bit images. this makes the DIB
	// conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
	// significantly more difficult to handle.

	if (m_buf==NULL) {
		AfxMessageBox("No Image!");
		return;
	}

	// image in m_buf is already BGR and vertically flipped, so we don't need
	// to do that for this function.

	// i really should make an RGB to BMP fn.

	BMPFile theBmpFile;
	theBmpFile.SaveBMP(filename,
						m_buf,
						m_width,
						m_height);

	if (theBmpFile.m_errorText!="OK") 
		AfxMessageBox(theBmpFile.m_errorText, MB_ICONSTOP);
	else {
		// load what we just saved
		LoadBMP(filename);
		Invalidate(TRUE);
	}


}

////////////////////////////////////////////////////////////////////////////
//
//	save a grayscaled image

void CMfcappView::OnFileSavegrayJPGas() 
{
	
	// note, because i'm lazy, most image data in this app
	// is handled as 24-bit images. this makes the DIB
	// conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
	// significantly more difficult to handle.
	
	CString fileName;
	CString filt="JPG File (*.JPG)|*.JPG|All files (*.*)|*.*||";
    
    // OPENFILENAME - so i can get to its Help page easily
	CFileDialog fileDlg(FALSE,"*.JPG","*.JPG",NULL,filt,this);
	fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
	fileDlg.m_ofn.lpstrTitle="File to save as grayscale";

	if (fileDlg.DoModal()==IDOK) {
	
		fileName=fileDlg.GetPathName();

		AfxGetApp()->DoWaitCursor(1);

		CString ext;
		ext=fileName.Right(4);

		if (!ext.CompareNoCase(".JPG"))
			SaveJPG(fileName,FALSE);

		AfxGetApp()->DoWaitCursor(-1);
	}
}

////////////////////////////////////////////////////////////////////////////
//
//	get JPG dimensions

void CMfcappView::OnFileGetdimensionsjpg() 
{
	CString fileName;
	CString filt="JPG File (*.JPG)|*.JPG|All files (*.*)|*.*||";
    
    // OPENFILENAME - so i can get to its Help page easily
	CFileDialog fileDlg(TRUE,"*.JPG","*.JPG",NULL,filt,this);

	fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
	fileDlg.m_ofn.lpstrTitle="File to examine";

	if (fileDlg.DoModal()==IDOK) {
		fileName=fileDlg.GetPathName();

		UINT width, height;
		if (JpegFile::GetJPGDimensions(fileName,
									&width,
									&height)) {
			char buf[200];
			sprintf(buf,"%d %d",width,height);
			AfxMessageBox(buf);
		} else
			AfxMessageBox("JPEG Error");
	}            
}



////////////////////////////////////////////////////////////////////////////
//
//	save 1,4,8 bit BMP from our 24-bit global buffer
//
//	if the user chooses 8-bits per pixel, we provide the option of using 
//	the color quantizer. 

void CMfcappView::OnFileSavecolormappedbmp() 
{

	if (m_buf==NULL) {
		AfxMessageBox("No Image!");
		return;
	}

	////////////////////////////////////////////////////////////////////////
	// get the filename
	CString fileName;
	CString filt="BMP (*.BMP)|*.BMP|All files (*.*)|*.*||";
    
    // OPENFILENAME - so i can get to its Help page easily
	CFileDialog fileDlg(FALSE,"*.BMP","*.BMP",NULL,filt,this);
	fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
	fileDlg.m_ofn.lpstrTitle="File to save as";

	if (fileDlg.DoModal()!=IDOK)
		return;

	fileName=fileDlg.GetPathName();

	////////////////////////////////////////////////////////////////////////
	// fetch bits per pixel
	CBMPDlg theDlg;
	if (theDlg.DoModal()!=IDOK)
		return;
	int bitsperpixel = theDlg.m_bits;

	AfxGetApp()->DoWaitCursor(1);

	////////////////////////////////////////////////////////////////////////
	// prepare for color-mapping
	
	// our palette
	RGBQUAD colormap[256];

	// num colors
	int colors = (int)pow(2,bitsperpixel);
	
	BYTE *colorMappedBuffer = NULL;

	// if we can use the color quantizer, we will
	if (bitsperpixel==8) {
		CQuantDlg theDlg;
		if (theDlg.DoModal()!=IDOK) {
			return;
		}

		// color or grayscale?
		if (theDlg.m_color) {

			// color !

			// allocate a buffer to colormap to
			colorMappedBuffer = (BYTE *)  new BYTE[m_width* m_height];

			if (colorMappedBuffer==NULL) {
				AfxMessageBox("Memory Error in OnSaveColormappedbmp!");
				return;
			}

			BYTE tmpPal[3][256];

			// colormap it 
			// generates an 8-bit color-mapped image into colorMappedBuffer
			if (!dl1quant(m_buf, 
								colorMappedBuffer,		// buffers
								m_width,
								m_height,	
								theDlg.m_quantColors,
								TRUE,
								tmpPal)) {				// palette
				AfxMessageBox("Quantization error");
				delete [] colorMappedBuffer;
				return;
			}
			// copy our palette
			for (UINT col=0;col<256;col++) {
				if (col>theDlg.m_quantColors) {
					colormap[col].rgbRed=0;
					colormap[col].rgbBlue=0;
					colormap[col].rgbGreen=0;
				} else {
					colormap[col].rgbRed=tmpPal[0][col];
					colormap[col].rgbGreen=tmpPal[1][col];
					colormap[col].rgbBlue=tmpPal[2][col];
				}
			}

		} else {
			// gray :(
			// convert to 8-bit colormapped grayscale
			colorMappedBuffer = MakeColormappedGrayscale(m_buf,					// RGB
														(UINT)m_width,			// pixels
														(UINT)m_height, 
														(UINT)m_width * 3,		// bytes
														(UINT)colors,			// colors
														colormap);				// palette
		}
	} else {	// bitsperpixel!=8

		// based on bitsperpixel, create a colormapped image
		colorMappedBuffer = MakeColormappedGrayscale(m_buf, 
													(UINT)m_width, 
													(UINT)m_height, 
													(UINT)m_width * 3, 
													(UINT)colors,
													colormap);
	}
	
	////////////////////////////////////////////////////////////////////////
	// finally, save the thing
	if (colorMappedBuffer!=NULL) {

		// write the BMP using our colormapped image (one byte per pixel, packed),
		// number of bits, number of total colors and a colormap
		// pixel values must be in the range [0...colors-1]

		BMPFile theBmpFile;

		theBmpFile.SaveBMP(fileName,					// path
							colorMappedBuffer,			// image
							m_width,					// pixels
							m_height,
							bitsperpixel,				// 1,4,8
							colors,						// num colors
							colormap);					// palette

		if (theBmpFile.m_errorText!="OK") {
			AfxMessageBox(theBmpFile.m_errorText, MB_ICONSTOP);
		}else {
			// load what we just saved
			LoadBMP(fileName);
			Invalidate(TRUE);
		}


		// toss our buffer...
		delete [] colorMappedBuffer;

	} else {
		AfxMessageBox("Failed to allocate space for RGB buffer");
	}

	AfxGetApp()->DoWaitCursor(-1);
}


////////////////////////////////////////////////////////////////////////
//	instead of creating a good palette for the colormapped images
//	this just graymaps them.
//

BYTE * CMfcappView::MakeColormappedGrayscale(BYTE *inBuf,
											  UINT inWidth,
											  UINT inHeight,
											  UINT inWidthBytes,
											  UINT colors,
											  RGBQUAD* colormap)
{
	////////////////////////////////////////////////////////////////////////	
	// allocate a buffer to colormap
	BYTE *tmp = (BYTE *)  new BYTE[inWidth * inHeight];
	if (tmp==NULL)
		return NULL;

	// force our image to use a stupid gray scale
	UINT color;
	for (color = 0;color < colors; color++) {
		colormap[color].rgbRed = color * 256 / colors;
		colormap[color].rgbGreen = color * 256 / colors;
		colormap[color].rgbBlue = color * 256 / colors;
	}


	UINT col, row;
	for (row =0; row < inHeight; row++) {

		for (col=0;col <inWidth; col++) {
			
			BYTE inRed, inBlue, inGreen;

			// src pixel
			long in_offset = row * inWidthBytes + col * 3;
			inRed = *(inBuf + in_offset + 0);
			inGreen = *(inBuf + in_offset + 1);
			inBlue = *(inBuf + in_offset + 2);

			// luminance
			int lum = (int)(.299 * (double)(inRed) + 
							.587 * (double)(inGreen) + 
							.114 * (double)(inBlue));

			// force luminance value into our range of colors
			lum = colors * lum / 256;

			// dest pixel
			long out_offset = row * inWidth + col;
			*(tmp+out_offset) = (BYTE)lum;
		}
	}

	return tmp;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -