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

📄 fractalview.cpp

📁 这是分行用于图像压缩的经典的程序,在正常的情况下可达到7:1左右的压缩比.
💻 CPP
字号:
// fractalView.cpp : implementation of the CFractalView class
//

#include "stdafx.h"
#include "fractal.h"
#include <fstream.h>
#include "fractalDoc.h"
#include "fractalView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CFractalView

IMPLEMENT_DYNCREATE(CFractalView, CView)

BEGIN_MESSAGE_MAP(CFractalView, CView)
	//{{AFX_MSG_MAP(CFractalView)
	ON_COMMAND(ID_ENCODE, OnEncode)
	ON_COMMAND(ID_DECODE, OnDecode)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFractalView construction/destruction

CFractalView::CFractalView()
{
	// TODO: add construction code here

	
	filename="file.txt";
	draw=0;


}

CFractalView::~CFractalView()
{
}

BOOL CFractalView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CFractalView drawing

void CFractalView::OnDraw(CDC* pDC)
{
	CFractalDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->flag == 1)
	{	
		SetDIBitsToDevice(pDC->m_hDC,0,0,pDoc->bi.biWidth,pDoc->bi.biHeight,0,0,0,pDoc->bi.biHeight,pDoc->lpBuf,pDoc->pbi,DIB_RGB_COLORS);
	    Invalidate(0);
	}

	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CFractalView printing

BOOL CFractalView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CFractalView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CFractalView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CFractalView diagnostics

#ifdef _DEBUG
void CFractalView::AssertValid() const
{
	CView::AssertValid();
}

void CFractalView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CFractalDoc* CFractalView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFractalDoc)));
	return (CFractalDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CFractalView message handlers

void CFractalView::OnEncode() 
{
	// TODO: Add your command handler code here
	
	CFractalDoc *pDoc=GetDocument();
	ASSERT_VALID(pDoc);
	CFileException ex;
	CDC *pDC=new CDC();
	int count=0;
 
/*	CFile fractal_file;
	if(!fractal_file.Open(filename,CFile::modeCreate|CFile::modeReadWrite,&ex))
	{
		TCHAR errorMessage[1024];
		ex.GetErrorMessage(errorMessage,1024);
		MessageBox(errorMessage);
		exit(1);
	}*/

   

	//定义变量
	Rect 
		image,reduced_image,domain_block,range_block,flip_range_block;
	AffineMap
		best_map;
	unsigned long 
		current_distance,minimum_distance,infinity;
	short 
		current_range_x,current_range_y,domain_x,domain_y;
	float 
		current_shift;
	float domain_mean;
	Symmetry current_symmetry;

	domain_block.width=DB_SIDE;
	domain_block.height=DB_SIDE;
	domain_block.length=DB_SIDE*DB_SIDE;
	domain_block.pixel= new int[DB_SIDE*DB_SIDE];
	if(!domain_block.pixel)
	{
		MessageBox("the  allocation of domain_block.pixel is error!",NULL,MB_OK);
		exit(1);
	}

	range_block.width=DB_SIDE;
	range_block.height=DB_SIDE;
	range_block.length=DB_SIDE*DB_SIDE;
	range_block.pixel= new int[DB_SIDE*DB_SIDE];
	if(!range_block.pixel)
	{
		MessageBox("the  allocation of range_block.pixel is error!",NULL,MB_OK);
		exit(1);
	}

	flip_range_block.width=DB_SIDE;
	flip_range_block.height=DB_SIDE;
	flip_range_block.length=DB_SIDE*DB_SIDE;
	flip_range_block.pixel= new int[DB_SIDE*DB_SIDE];
	if(!flip_range_block.pixel)
	{
		MessageBox("the  allocation of flip_range_block.pixel is error!",NULL,MB_OK);
		exit(1);
	}

	//分配很大的一个数
	infinity=255*255*DB_SIDE*DB_SIDE;

	//开始对image和reduced_image进行操作
	int cxDIB=(int)pDoc->bi.biWidth;
	int cyDIB=(int)pDoc->bi.biHeight;

	int width=cxDIB;
	int height=cyDIB;

	image.width=width;
	image.height =height;
	image.length=(unsigned long)(width*height);
	image.pixel=new int[image.length];
	if(!image.pixel )
	{
		MessageBox("the allocation of image.pixel is error!");
		exit(1);
	}

    reduced_image.width=width/2;
	reduced_image.height =height/2;
	reduced_image.length=(unsigned long)(width*height/4);
	reduced_image.pixel=new int[reduced_image.length];
	if(!reduced_image.pixel )
	{
		MessageBox("the allocation of reduced_image.pixel is error!");
		exit(1);
	}

	DWORD num=pDoc->bi.biSizeImage;
	BYTE *buff=new BYTE[num];
	buff=pDoc->lpBuf;

	for(unsigned long i=0;i<image.length ;i++)
	{
		image.pixel[i]=buff[i];
	}

	reduce_image(&image,&reduced_image);


    
    ofstream fractal_file("file.txt",ios::binary); 

	//创建一个.txt文件

	for( domain_y = 0; domain_y < image.height; domain_y += DB_SIDE )	

		for( domain_x = 0; domain_x < image.width; domain_x += DB_SIDE )
		{
			minimum_distance=infinity;
			copy_rectangle(&image,domain_x,domain_y,&domain_block,0,0,DB_SIDE,DB_SIDE);
			domain_mean=mean(&domain_block);
			
  
           
			for(current_range_y=0;current_range_y<=reduced_image.height-DB_SIDE;current_range_y++) 
			{
				for(current_range_x=0;current_range_x<=reduced_image.width-DB_SIDE;current_range_x++)
				{
				   copy_rectangle(&reduced_image,current_range_x,current_range_y,&range_block,0,0,DB_SIDE,DB_SIDE);
				   current_shift=domain_mean-mean(&range_block);
				   intensity(&range_block,&current_shift);
				   for(current_symmetry=0;current_symmetry<NSYSM;current_symmetry++)
				   {
					   flip(&range_block,&flip_range_block,current_symmetry);
					   current_distance=two_distance(&domain_block,&flip_range_block);
						if(current_distance<minimum_distance)
						{
							minimum_distance=current_distance;
							best_map.range_x=current_range_x;
							best_map.range_y=current_range_y;
							best_map.symmetry=current_symmetry;
							best_map.shift=current_shift;
					
						}

			 
				   }
				}


			}
				
				
				
                

				fractal_file.write((char*)(&best_map.range_x),sizeof(best_map.range_x));
				fractal_file.write((char*)(&best_map.range_y),sizeof(best_map.range_y));
                fractal_file.write((char*)(&best_map.symmetry),sizeof(best_map.symmetry));
			
				fractal_file.write((char*)(&best_map.shift ), sizeof(best_map.shift ));

                CClientDC pDC(this);
				CString str;
				str.Format("%ld",count++);
				CPen pen;
				pen.CreatePen(PS_SOLID,100,RGB(0,255,0));
				pDC.SelectObject(pen);
				UpdateData(true);
				pDC.TextOut(cxDIB+10,10,str);
	
	
}
   CClientDC client(this);
	client.TextOut(cxDIB+10,10,"end");
	

}

void CFractalView::reduce_image(Rect *src_dest, Rect *dest_rect)
{

    int  i,j;
	for(j=0;j<dest_rect->height;j++)
		for(i=0;i<dest_rect->width ;i++)
		{
			dest_rect->pixel[i+j*dest_rect->width]=
				src_dest->pixel[2*i+2*j*src_dest->width]+
				src_dest->pixel[2*i+1+2*j*src_dest->width]+
				src_dest->pixel[2*i+(2*j+1)*src_dest->width]+
				src_dest->pixel[2*i+1+(2*j+1)*src_dest->width];
		
		dest_rect->pixel[i+j*dest_rect->width]=((unsigned int)dest_rect->pixel[i+j*dest_rect->width]*3)/16;

		}
}







float CFractalView::mean(Rect *rectangle)
{
	unsigned long i;
	long sum=0;
	for(i=0;i<rectangle->length ;i++)
	{
		sum+=rectangle->pixel[i];
	}
	return (float)(sum*1.0/rectangle->length);

	
}


void CFractalView::intensity(Rect *rectangle, float *shift)
{
unsigned long  i;
    float j;
	for(i=0;i<rectangle->length ;i++)
	{
		j=(float)(rectangle->pixel[i]+(*shift+0.5));
		if(j<-32000)
			rectangle->pixel[i]=-32000;
		if(j>32000)
			rectangle->pixel[i]=32000;
		if(j>-32000&&j<32000)
			rectangle->pixel[i]=(int)j;
	}


}

long CFractalView::two_distance(Rect *rect1, Rect *rect2)
{

	long d=0;
	unsigned long distance=0;
	for(unsigned long  i=0;i<rect1->length;i++)
	{
		d=rect1->pixel[i]-rect2->pixel[i];
		distance+=d*d;
	}
	return distance;

}

void CFractalView::flip(Rect *range_block, Rect *flip_range_block, Symmetry symmetry)
{
short i,j,x,y,t;
for(j=0;j<range_block->height;j++)
  for(i=0;i<range_block->width;i++)
  {
	  if(symmetry&FILP_X)
		  x=(range_block->width-1)-i;
	  else 
		  x=i;

	  if(symmetry&FILP_Y)
		  y=(range_block->height-1)-j;
	  else 
		  y=j;

	  if(symmetry&FILP_DIAG)
	  {
		 t=x;
		 x=y;
		 y=t;
	  }

	  flip_range_block->pixel[x+y*range_block->width]=
		  range_block->pixel[i+j*range_block->width];
  }



}


void CFractalView::copy_rectangle(Rect *src_rect, short src_x, short src_y, Rect *dest_rect, short dest_x, short dest_y, short width, short height)
{
   int   i,j;
	for(j=0;j<height;j++)
		for(i=0;i<width;i++)
		{
			 dest_rect->pixel[i+dest_x+(j+dest_y)*dest_rect->width]=
				src_rect->pixel[i+src_x+(j+src_y)* src_rect->width];
		}
    return ;

}
  

void CFractalView::OnDecode() 
{
	// TODO: Add your command handler code here

 CFractalDoc* pDoc = GetDocument();
#define ITERATE 8
	ASSERT_VALID(pDoc);
	AffineMap
		*affine_map_array, *map_ptr;
	CFile
		newFile;
	int
		iterate;
	
	long
		number_of_maps,i;
	short
		domain_x,domain_y;
	Rect
		image,reduced_image,range_block,transformed_range_block;


	//打开压缩的文本文件
	char *szFilter = "Text File(*.txt)|*.*||";
	CFileDialog dlg(TRUE,"txt",TEXT("Readme.txt"),OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);
	if(dlg.DoModal()!=IDOK)
	{
		return;
	}
	CString name = dlg.GetFileName();//得到文件名称
	if(name!=filename)
	{
		MessageBox("打开文件出错,请再次打开文件",NULL,MB_OK);
		return;
	}
	CFileException ex;



	ifstream fractal_file("file.txt",ios::binary);
	

	//得到位图文件名称,生成一个新的位图文件


    CString copyBitmapName;
    copyBitmapName = pDoc->bitmapName;

    CString temp = pDoc->bmPath;
    copyBitmapName = "Second" + copyBitmapName;

 //  ofstream newFile("copyBitmapName",ios::binary);


	if(!newFile.Open(copyBitmapName,CFile::modeCreate|CFile::modeWrite,&ex))
		//以写的方式打开文件 
	{
		TCHAR errorMessage[1024];
	    ex.GetErrorMessage(errorMessage,1024);
		MessageBox(errorMessage);
		exit(1);
	}
	

    BITMAPFILEHEADER bf = pDoc->bf;
	BITMAPINFOHEADER bi = pDoc->bi;
    RGBQUAD *quad = pDoc->quad;
   	int numQuad = pDoc->numQuad;
	newFile.Write(&bf,sizeof(bf));
	newFile.Write(&bi,sizeof(bi));
	newFile.Write(quad,sizeof(quad)*numQuad);




	

	int width = pDoc->bi.biWidth;
	int height = pDoc->bi.biHeight;
	number_of_maps = 
		width*height/(DB_SIDE*DB_SIDE);
	affine_map_array = 
		new AffineMap[number_of_maps];
	if(!affine_map_array)
	{
		MessageBox("the Allocation of affine_map_array is error",NULL,MB_OK);
		return;
	}
	
	image.width = width;
	image.height = height;
	image.length = width*height;
	image.pixel = new int[image.length];
	if(!image.pixel)
	{
		MessageBox("the Allocation of image.pixel is error",NULL,MB_OK);
		return;
	}

	reduced_image.width = width/2;
	reduced_image.height = height/2;
	reduced_image.length = width*height/4;
	reduced_image.pixel = new int[reduced_image.length];
	if(!reduced_image.pixel)
	{
		MessageBox("the Allocation of reduced_pixel is error",NULL,MB_OK);
		return;
	}

	range_block.width = DB_SIDE;
	range_block.height = DB_SIDE;
	range_block.length = DB_SIDE*DB_SIDE;
	range_block.pixel =
		new int[range_block.length];
	if(!range_block.pixel)
	{
		MessageBox("the Allocation of range_block.pixel is error",NULL,MB_OK);
		return;
	}

	transformed_range_block.width = DB_SIDE;
    transformed_range_block.height = DB_SIDE;
	transformed_range_block.length = DB_SIDE*DB_SIDE;
    transformed_range_block.pixel = new int [transformed_range_block.length];
	if(!transformed_range_block.pixel)
	{
		MessageBox("the Allocation of transformed_range_block.pixel is error",NULL,MB_OK);
		return;
	}


	for(i = 0;i<image.length;i++)
	{
		image.pixel[i] = ARBITRARY_PIXEL_VALUE;
	}


	

	for(domain_y = 0,map_ptr = affine_map_array;domain_y<image.height;domain_y+=DB_SIDE)
		for(domain_x = 0;domain_x<image.width;domain_x+=DB_SIDE,map_ptr++)
		{
			//读信息

			fractal_file.read((char *)&map_ptr->range_x,sizeof(map_ptr->range_x));
			fractal_file.read((char *)&map_ptr->range_y,sizeof(map_ptr->range_y));
			fractal_file.read((char *)&map_ptr->symmetry,sizeof(map_ptr->symmetry));
			fractal_file.read((char *)&map_ptr->shift,sizeof(map_ptr->shift));

		}

	fractal_file.close();
    int num = 0;
	
	for(iterate = 0;iterate<ITERATE;iterate++)
	{
		reduce_image(&image,&reduced_image);

	
		for(domain_y = 0,map_ptr = affine_map_array;domain_y<image.height;domain_y+=DB_SIDE)
			for(domain_x = 0;domain_x<image.width;domain_x+=DB_SIDE,map_ptr++)
			{
					
					 
                     num++;
					 if(num>image.width*image.height)
						 break;
					 copy_rectangle(&reduced_image,map_ptr->range_x,map_ptr->range_y,
						             &range_block,0,0,DB_SIDE,DB_SIDE);
					 intensity(&range_block,&(map_ptr->shift));

					

					 flip(&range_block,&transformed_range_block,map_ptr->symmetry);

					
					 

                    copy_rectangle(&transformed_range_block,0,0,&image,domain_x,domain_y,DB_SIDE,DB_SIDE);
					 
			}
	}



   unsigned char *buff = new unsigned char[image.length];

	if(!buff)
	{
		MessageBox("The allocation of is invalidate",NULL,MB_OK);
		return;
	}
	for(i = 0;i<image.length;i++)
	{
		if(image.pixel[i]>255) 
			buff[i] = 255;
		if(image.pixel[i]<0)   
			buff[i] = 0;
		if(image.pixel[i]>=0&&image.pixel[i]<=255) 
			buff[i] = image.pixel[i];
		
	}
	


	for(unsigned long j=0;j<image.length;j++)
	{
	   newFile.Write(&buff[j],sizeof(buff[j]));
	}

	delete map_ptr;

	delete affine_map_array;
	delete image.pixel;
	delete reduced_image.pixel;
    
	newFile.Close();

   }





⌨️ 快捷键说明

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