📄 dib.cpp
字号:
// DIB.cpp
#include "stdafx.h"
#include "DIB.h"
#include "Statics.h"
#include <math.h>
#include <stdio.h>
#include <process.h>
#define pi 3.14159265
FILE *stream;
CDib::CDib()
{
// Set the Dib pointer to
// NULL so we know if it's
// been loaded.
m_pDib = NULL;
m_pWordData = NULL;
}
CDib::~CDib()
{
// If a Dib has been loaded,
// delete the memory.
if( m_pDib != NULL )
delete [] m_pDib;
if( m_pWordData != NULL )
delete [] m_pWordData;
}
BOOL CDib::Load( const char *pszFilename )
{
CFile cf;
// Attempt to open the Dib file for reading.
if( !cf.Open( pszFilename, CFile::modeRead ) )
return( FALSE );
// Get the size of the file and store
// in a local variable. Subtract the
// size of the BITMAPFILEHEADER structure
// since we won't keep that in memory.
DWORD dwDibSize;
dwDibSize =
cf.GetLength() - sizeof( BITMAPFILEHEADER );
// Attempt to allocate the Dib memory.
unsigned char *pDib;
pDib = new unsigned char [dwDibSize];
if( pDib == NULL )
return( FALSE );
BITMAPFILEHEADER BFH;
// Read in the Dib header and data.
try{
// Did we read in the entire BITMAPFILEHEADER?
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||
// Is the type 'MB'?
BFH.bfType != 'MB' ||
// Did we read in the remaining data?
cf.Read( pDib, dwDibSize ) != dwDibSize ){
// Delete the memory if we had any
// errors and return FALSE.
delete [] pDib;
return( FALSE );
}
}
// If we catch an exception, delete the
// exception, the temporary Dib memory,
// and return FALSE.
catch( CFileException *e ){
e->Delete();
delete [] pDib;
return( FALSE );
}
cf.Close();
// If we got to this point, the Dib has been
// loaded. If a Dib was already loaded into
// this class, we must now delete it.
if( m_pDib != NULL )
delete m_pDib;
// Store the local Dib data pointer and
// Dib size variables in the class member
// variables.
m_pDib = pDib;
m_dwDibSize = dwDibSize;
// Pointer our BITMAPINFOHEADER and RGBQUAD
// variables to the correct place in the Dib data.
m_pBIH = (BITMAPINFOHEADER *) m_pDib;
m_pPalette =
(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
// Calculate the number of palette entries.
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
if( m_pBIH->biBitCount > 8 )
m_nPaletteEntries = 0;
else if( m_pBIH->biClrUsed != 0 )
m_nPaletteEntries = m_pBIH->biClrUsed;
// Point m_pDibBits to the actual Dib bits data.
m_pDibBits =
&m_pDib[sizeof(BITMAPINFOHEADER)+
m_nPaletteEntries*sizeof(RGBQUAD)];
// If we have a valid palette, delete it.
if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();
// If there are palette entries, we'll need
// to create a LOGPALETTE then create the
// CPalette palette.
if( m_nPaletteEntries != 0 ){
// Allocate the LOGPALETTE structure.
LOGPALETTE *pLogPal = (LOGPALETTE *) new char
[sizeof(LOGPALETTE)+
m_nPaletteEntries*sizeof(PALETTEENTRY)];
if( pLogPal != NULL ){
// Set the LOGPALETTE to version 0x300
// and store the number of palette
// entries.
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = m_nPaletteEntries;
// Store the RGB values into each
// PALETTEENTRY element.
for( int i=0; i<m_nPaletteEntries; i++ ){
pLogPal->palPalEntry[i].peRed =
m_pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen =
m_pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue =
m_pPalette[i].rgbBlue;
}
// Create the CPalette object and
// delete the LOGPALETTE memory.
m_Palette.CreatePalette( pLogPal );
delete [] pLogPal;
}
}
m_BitCount = 8;
return( TRUE );
}
BOOL CDib::Save( const char *pszFilename )
{
// If we have no data, we can't save.
if( m_pDib == NULL )
return( FALSE );
CFile cf;
// Attempt to create the file.
if( !cf.Open( pszFilename,
CFile::modeCreate | CFile::modeWrite ) )
return( FALSE );
// Write the data.
try{
// First, create a BITMAPFILEHEADER
// with the correct data.
BITMAPFILEHEADER BFH;
memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
BFH.bfType = 'MB';
BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
m_nPaletteEntries * sizeof( RGBQUAD );
// Write the BITMAPFILEHEADER and the
// Dib data.
cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
cf.Write( m_pDib, m_dwDibSize );
}
// If we get an exception, delete the exception and
// return FALSE.
catch( CFileException *e ){
e->Delete();
return( FALSE );
}
return( TRUE );
}
BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight, int Style )
{
long i,j;
// If we have not data we can't draw.
if( m_pDib == NULL )
return( FALSE );
// if this is an 16/12 bit image,
// we should map the 16/12 data to 8 bit
long vWidth = (4 - m_pBIH->biWidth % 4) % 4 + m_pBIH->biWidth;
if ( m_BitCount != 8)
{
for (i = 0; i< m_pBIH->biHeight; i++)
for (j = 0; j < m_pBIH->biWidth; j++)
{
*(m_pDibBits+i*vWidth+j) = (m_pWordData[i*m_pBIH->biWidth+j] >> (m_BitCount-8));
}
}
else if ( m_BitCount == 16)
{
for (i = 0; i< m_pBIH->biWidth*m_pBIH->biHeight; i++)
{
m_pDibBits[i] = (m_pWordData[i] >> 8);
}
}
// Check for the default values of -1
// in the width and height arguments. If
// we find -1 in either, we'll set them
// to the value that's in the BITMAPINFOHEADER.
if( nWidth == -1 )
nWidth = m_pBIH->biWidth;
if( nHeight == -1 )
nHeight = m_pBIH->biHeight;
if (Style) // non_zero: Use StretchDIBits to draw the Dib.
{
StretchDIBits( pDC->m_hDC, nX, nY,
nWidth, nHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY );
}
else
{
SetDIBitsToDevice( pDC->m_hDC, nX, nY,
m_pBIH->biWidth, m_pBIH->biHeight,
0, 0,
0, m_pBIH->biHeight,//nHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB);
}
return( TRUE );
}
BOOL CDib::SetPalette( CDC *pDC )
{
// If we have not data we
// won't want to set the palette.
if( m_pDib == NULL )
return( FALSE );
// Check to see if we have a palette
// handle. For Dibs greater than 8 bits,
// this will be NULL.
if( m_Palette.GetSafeHandle() == NULL )
return( TRUE );
// Select the palette, realize the palette,
// then finally restore the old palette.
CPalette *pOldPalette;
pOldPalette = pDC->SelectPalette( &m_Palette, FALSE );
pDC->RealizePalette();
pDC->SelectPalette( pOldPalette, FALSE );
return( TRUE );
}
bool CDib::ConvertToTwoValue()
{
DWORD i,size;
unsigned char *p;
// 一个特别简单的二值化程序
// 以128为界划分
p = m_pDibBits;
size = m_dwDibSize - (m_pDibBits - m_pDib);
for (i = 0; i < size;i++)
{
if (*p < 128)
{
*p = 0;
}
else
{
*p = 255;
}
p++;
}
return true;
}
int CDib::ConvertToMAXvalue()
{ int j=0;
DWORD i,size;
unsigned char *p;
//get maxvalue
p = m_pDibBits;
size = m_dwDibSize - (m_pDibBits - m_pDib);
for (i = 0; i < size;i++)
{
if (*p >j)
{
j=*p ;
}
p++;
}
return j;
}
int CDib::ConvertToMINvalue()
{ int j=255;
DWORD i,size;
unsigned char *p;
//get maxvalue
p = m_pDibBits;
size = m_dwDibSize - (m_pDibBits - m_pDib);
for (i = 0; i < size;i++)
{
if (*p <j)
{
j=*p ;
}
p++;
}
return j;
}
int CDib::ConvertToAVERAGEvalue()
{ int j=0;
DWORD i,size;
unsigned char *p;
//get maxvalue
p = m_pDibBits;
size = m_dwDibSize - (m_pDibBits - m_pDib);
for (i = 0; i < size;i++)
{
j=*p+j ;
p++;
}
j=j/size;
return j;
}
bool CDib::ConvertToHISTOGRAMvalue(int L)
{ //直方图均衡化
float *M;
M=new float [L];
int *N;
N=new int [L];
int a=0;
int j=0;
DWORD i,size;
unsigned char *p;
p = m_pDibBits;
size = m_dwDibSize - (m_pDibBits - m_pDib);
for (j=0;int(j)<L;j++){
M[j]=0.0;
}
for (j=0;int(j)<L;j++){
N[j]=0;
}
for (i = 0; i < size;i++)
{
a= int((*p) *L/ 256);
M[a]++;
p++;
}
for (j=0;int(j)<L;j++){
M[j]=M[j]/size;
if(j>1) M[j]+=M[j-1];
}
for(j=0;int(j)<L;j++){N[j]=int((L -1)*M[j]+0.5);}
p=m_pDibBits;//直方图指针p复位
for (i= 0; i< size;i++)
{
a= (*p) *L/ 256;
*p= N[a]*256/L;
p++;
}
return true;
}
int *CDib::ConvertToDRAWHISTOGRAMvalue()
{ //求直方图
int *his;
his=new int [256];
int a=0;
int j=0;
DWORD i,size;
unsigned char *p;
p = m_pDibBits;
size = m_dwDibSize - (m_pDibBits - m_pDib);
for (i=0;i<256;i++)
{his[i]=0;
}
for (i = 0; i < size;i++)
{
a= int(*p);
his[a]++;
p++;
}
//***********************
for (i = 0; i < 256;i++)
{
if (j<his[i]) {j=his[i];}
}
for (i = 0; i < 256;i++)
{
his[i]=int(his[i]*100/j);
}
return his;
}
bool CDib::ConvertToMEDIANvalue(int n)
{/* DWORD i,size;
unsigned char *p;
long vWidth = (4 - m_pBIH->biWidth % 4) % 4 + m_pBIH->biWidth;
int y,x,yy,xx,n2,nn,chuo,chg,medi,madom,mado[1000];
int m=0;
int **me;
me= new int *[m_pBIH->biHeight];
for (i=0;i<m_pBIH->biHeight;i++)
{ me[i]=new int [m_pBIH->biWidth];
}
int **mo;
mo= new int *[m_pBIH->biHeight];
for (i=0;i<m_pBIH->biHeight;i++)
{ mo[i]=new int [m_pBIH->biWidth];
}
p = m_pDibBits;
size = m_dwDibSize - (m_pDibBits - m_pDib);
if (n<3||n%2!=1) return true;
n2=(n-1)/2;
nn=n*n;
chuo=(nn-1)/2;
for (y=0;y<m_pBIH->biHeight;y++)
{ for (x=0;x<m_pBIH->biWidth;x++)
{ me[y][x]=*p;
mo[y][x]=0;
p++;
}
}
p = m_pDibBits;
for (y=n2;y<m_pBIH->biHeight-n2;y++)
{
for (x=n2;x<m_pBIH->biWidth-n2;x++)
{
m=0;
for (yy=y-n2;yy<=y+n2;yy++)
for (xx=x-n2;xx<=x+n2;xx++)
{
mado[m]=me[yy][xx];
m++;
}
do
{
chg=0;
for (m=0;m<nn-1;m++)
{
if (mado[m]<mado[m+1])
{
madom=mado[m];
mado[m]=mado[m+1];
mado[m+1]=madom;
chg=1;
}
}
}
while(chg==1);
medi=mado[chuo];
mo[y][x]=medi;
}
}
// for (y = 0; y< m_pBIH->biHeight; y++)
// for (x = 0; x < m_pBIH->biWidth; x++)
// {p = m_pDibBits;
// p=p+y*vWidth+x;*p=mo[y][x];
for (y=0;y<m_pBIH->biHeight;y++)
{ for (x=0;x<m_pBIH->biWidth;x++)
{
*p=mo[y][x];
p++;
}
}
*/
int Len,Wid;
//int n=5;
int i=0,j=0,k=0,l=0,m=0;int H[25]={0};
unsigned char *p;
p = m_pDibBits;
Wid=m_pBIH->biWidth;
Len = m_pBIH->biHeight;
int **M;
M=new int *[Len];
for(i=0;i<Len;i++){M[i]=new int[Wid];}
int **N;
N=new int *[Len];
for(i=0;i<Len;i++){N[i]=new int[Wid];}
for (i = 0; i <Len;i++)
for(j=0; j<Wid;j++)
{M[i][j]=*p;N[i][j]=*p;p++;
}
for(i=0;i<Len-n;i++)
for(j=0;j<Wid-n;j++)
{ k=0;
for(l=0;l<n;l++)
{for(m=0;m<n;m++)
{H[k]=M[i+l][j+m];k++;}
}
for(l=0;l<n*n-1;l++){
for(m=l+1;m<n*n;m++){if(H[l]>H[m])
{k=H[l];H[l]=H[m];H[m]=k;}
}
}
N[i+n/2][j+n/2]=H[n*n/2];
}
p = m_pDibBits;
for(i=0;i<Len;i++)
for(j=0;j<Wid;j++)
{*p=N[i][j];p++;}
return true;
}
//***********************************************
bool CDib::ConvertToSobelvalue()
{ int Len,Wid,temp1=0,temp2=0;
int i=0,j=0;
unsigned char *p;
p = m_pDibBits;
Wid=m_pBIH->biWidth;
Len = m_pBIH->biHeight;
int **M;
M=new int *[Len];
for(i=0;i<Len;i++){M[i]=new int[Wid];}
int **N;
N=new int *[Len];
for(i=0;i<Len;i++){N[i]=new int[Wid];}
for (i = 0; i <Len;i++)
for(j=0;j<Wid;j++)
{M[i][j]=*p;N[i][j]=*p;p++;
}
for(i=1;i<Len-1;i++)
for(j=1;j<Wid-1;j++)
{temp1=-M[i-1][j-1]+M[i-1][j+1]-M[i][j-1]+M[i][j+1]-2*M[i+1][j-1]+2*M[i+1][j+1];
temp2=-M[i-1][j-1]+M[i+1][j-1]-M[i-1][j]+M[i+1][j]-2*M[i-1][j+1]+2*M[i+1][j+1];
temp1=abs(temp1);temp2=abs(temp2);
if(temp1>temp2){N[i][j]=temp1;}
else N[i][j]=temp2;
}
p = m_pDibBits;
for(i=0;i<Len;i++)
for(j=0;j<Wid;j++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -