目录
一、bmp文件头、文件信息头、位图实际数据的数据结构定义
二、源BMP文件信息的读取
三、实际位图数据的旋转、缩放操作
四、生成转换过后的新位图文件
#include <stdlib.h>
#ifndef PHOTODEAL_H
#define PHOTODEAL_H
#pragma pack(1)
typedef struct tagBmpFileHeader{
unsigned short bfType;
unsigned long bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned long bfOffBits;
}BMPFILEHEADER;
typedef struct tagBmpInfoHeader{
unsigned long biSize;
long biWidth;
long biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
}BMPINFOHEADER;
typedef struct tagPalEn{
unsigned char rgbRed;
unsigned char rgbGreen;
unsigned char rgbBlue;
unsigned char rgbFlags;
}PALEN;
typedef struct tagPalette{
unsigned short palVersion;
unsigned short palNumEntries;
PALEN palPalEN[1];
}PALETTE;
#pragma pack()
void OnLoad(char* path, BMPFILEHEADER* srcBmpFileHeader, BMPINFOHEADER* srcBmpInfoHeader, unsigned char** srcBmpData);
void WriteData(char* path, BMPFILEHEADER* desBmpFileHeader, BMPINFOHEADER* desBmpInfoHeader, unsigned char* desBmpData);
void RotateBmp(BMPFILEHEADER* srcBmpFileHeader, BMPINFOHEADER* srcBmpInfoHeader, BMPFILEHEADER* desBmpFileHeader, BMPINFOHEADER* desBmpInfoHeader, unsigned char** srcBmpData, /*double dAngle,*/ unsigned char* desBmpData);
void ZoomBmp(BMPFILEHEADER* srcBmpFileHeader, BMPINFOHEADER* srcBmpInfoHeader, BMPFILEHEADER* desBmpFileHeader, BMPINFOHEADER* desBmpInfoHeader,
unsigned char* srcBmpData, unsigned char** desBmpData /*, int zmHeight, int zmWidth, , double dxRate, double dyRate*/);
void start();
//void suofang();
#endif
#define _CRT_SECURE_NO_WARNINGS
#include "PHOTODEAL.h"
#include <stdio.h>
//#include <stdlib.h>
#include <string.h>
#include <math.h>
BMPFILEHEADER srcBmpFileHeader, desBmpFileHeader;
BMPINFOHEADER srcBmpInfoHeader, desBmpInfoHeader;
unsigned char* srcBmpData = NULL;
unsigned char* desBmpData = NULL;
void OnLoad(char* path, BMPFILEHEADER* srcBmpFileHeader, BMPINFOHEADER* srcBmpInfoHeader, unsigned char** srcBmpData){
FILE* pFile;
unsigned char* tempData;//临时存储转换前的源图数据
pFile = fopen(path, "rb");
if (pFile == NULL){
printf("Cann't open the file %s", path);
}
//读取文件头
fread(srcBmpFileHeader, sizeof(BMPFILEHEADER), 1, pFile);
printf("\n==============================================================\n");
printf("文件类型标识符:0x%x\n", srcBmpFileHeader->bfType);
printf("文件大小:%d_%d(kb)\n", srcBmpFileHeader->bfSize, srcBmpFileHeader->bfSize / 1024);
printf("保留字1:%d\n保留字2:%d\n", srcBmpFileHeader->bfReserved1, srcBmpFileHeader->bfReserved2);
printf("文件头开始到位图实际数据开始位的偏移字节:%d\n", srcBmpFileHeader->bfOffBits);
//读取文件信息头
fread(srcBmpInfoHeader, sizeof(BMPINFOHEADER), 1, pFile);
printf("\n==============================================================\n");
printf("文件信息头大小:%d\n", srcBmpInfoHeader->biSize);
printf("位图宽度,像素:%d\n", srcBmpInfoHeader->biWidth);
printf("位图高度,像素:%d\n", srcBmpInfoHeader->biHeight);
printf("位图实际数据大小:%d_%d(kb)\n", srcBmpInfoHeader->biSizeImage, srcBmpInfoHeader->biSizeImage / 1024);
printf("位图颜色使用的调色板数量:%d\n", srcBmpInfoHeader->biPlanes);
printf("位图颜色使用的位(bit): %d\n", srcBmpInfoHeader->biBitCount);
printf("位图实际使用的颜色数:%d\n", srcBmpInfoHeader->biClrUsed);
printf("位图使用的重要颜色数:%d\n", srcBmpInfoHeader->biClrImportant);
printf("位图是否压缩:%d\n", srcBmpInfoHeader->biCompression);
//读取位图实际数据
printf("\n==============================================================\n");
tempData = (unsigned char*)malloc(sizeof(unsigned char)*srcBmpInfoHeader->biSizeImage);
memset(tempData, 0, srcBmpInfoHeader->biSizeImage);
if (srcBmpInfoHeader->biBitCount == 24){
printf("该图为真彩色图 !\n");
fread(tempData, sizeof(unsigned char), sizeof(unsigned char)*srcBmpInfoHeader->biSizeImage, pFile);//临时存储读取的转换前源图数据
fclose(pFile);
//将位图数据转换为每个像素4字节形式,计算转换后的图像大小
int sizeofbuff = srcBmpInfoHeader->biWidth * srcBmpInfoHeader->biHeight * 4;
//计算位图每行填充的字节数
int externWidth = srcBmpInfoHeader->biWidth * 3;
(externWidth % 4 != 0) ? (externWidth = 4 - externWidth % 4) : (externWidth = 0);
//为转换后的位图数据分配空间
*srcBmpData = (unsigned char*)malloc(sizeof(unsigned char) * sizeofbuff);
//复制转换后的数据到srcBmpData
int k = 0;
for (/*int i = srcBmpInfoHeader->biHeight - 1; i >= 0; i--*/int i = 0; i < srcBmpInfoHeader->biHeight; i++){
for (int j = 0; j < srcBmpInfoHeader->biWidth * 3; j += 3){
(*srcBmpData)[k] = tempData[i * (srcBmpInfoHeader->biWidth * 3 + externWidth) + j + 0];
(*srcBmpData)[k + 1] = tempData[i * (srcBmpInfoHeader->biWidth * 3 + externWidth) + j + 1];
(*srcBmpData)[k + 2] = tempData[i * (srcBmpInfoHeader->biWidth * 3 + externWidth) + j + 2];
(*srcBmpData)[k + 3] = 255;//第四位填充为255
k += 4;
}
}
free(tempData);
}
}
void WriteData(char* path, BMPFILEHEADER* desBmpFileHeader, BMPINFOHEADER* desBmpInfoHeader, unsigned char* desBmpData){
FILE* pFile;
/*char* tempName;
char* newName;
memcpy(tempName, path, strlen(path) - 4);*/
pFile = fopen(path, "wb");
//写入文件头
fwrite(desBmpFileHeader, sizeof(BMPFILEHEADER), 1, pFile);
//写入文件信息头
fwrite(desBmpInfoHeader, sizeof(BMPINFOHEADER), 1, pFile);
//写入位图实际数据
unsigned int outHeight = desBmpInfoHeader->biHeight;
unsigned int outWidth = desBmpInfoHeader->biWidth;
//指向旋转的图像数据的最后一行
/*unsigned char** pListData = NULL;
pListData = &desBmpData + ((unsigned long)outHeight - 1) * outWidth * 4;
不需要这段代码*/
//计算需要填充的字节数
unsigned char byByteAlign;
if (outWidth % 4 != 0)
byByteAlign = 4 - ((outWidth * 3) % 4);
else
byByteAlign = 0;
unsigned char byZeroData = 0;
for (unsigned int i = 0; i < outHeight; i++){
for (unsigned int j = 0; j < outWidth; j++){
fwrite(desBmpData, sizeof(unsigned char), 3, pFile);//写入位图实际数据
desBmpData += 4;//指向下一个像素
}
for (int k = 0; k < byByteAlign; k++){
fwrite(&byZeroData, sizeof(unsigned char), 1, pFile);
}
}
//free(&pListData);
fclose(pFile);
printf("\n文件转换保存成功 !\n");
}
void RotateBmp(BMPFILEHEADER* srcBmpFileHeader, BMPINFOHEADER* srcBmpInfoHeader, BMPFILEHEADER* desBmpFileHeader, BMPINFOHEADER* desBmpInfoHeader,
unsigned char* srcBmpData, /*double dAngle,*/ unsigned char** desBmpData){
double dAngle;
printf("\n请输入旋转角度:\n");
scanf("%lf", &dAngle);
//角度转弧度,计算正弦、余弦
double PI = 3.141592653;
double dRadian = dAngle * PI / 180.0;
double dSin = sin(dRadian);
double dCos = cos(dRadian);
//计算目标图像的高度、宽度
*desBmpFileHeader = *srcBmpFileHeader;
*desBmpInfoHeader = *srcBmpInfoHeader;
desBmpInfoHeader->biHeight = (int)((abs)(srcBmpInfoHeader->biHeight * dCos) + (abs)(srcBmpInfoHeader->biWidth * dSin) + 1);
desBmpInfoHeader->biWidth = (int)((abs)(srcBmpInfoHeader->biHeight * dSin) + (abs)(srcBmpInfoHeader->biWidth * dCos) + 1);
printf("desWidth = %d - desHeight = %d\n", desBmpInfoHeader->biWidth, desBmpInfoHeader->biHeight);
//计算每行字节数及填充字节数
//unsigned int desLineBytes = desBmpInfoHeader->biWidth * desBmpInfoHeader->biBitCount / 8; 此方式计算结果小于实际需求
unsigned int desLineBytes = desBmpInfoHeader->biWidth * 4;
printf("\n目标每行字节数:%d\n", desLineBytes);
int mod = desLineBytes % 4;
if (mod != 0)
desLineBytes += 4 - mod;
//为目标图像数据分配空间
desBmpInfoHeader->biSizeImage = desBmpInfoHeader->biHeight * desLineBytes;
printf("\n目标图像数据大小:%d\n", desBmpInfoHeader->biSizeImage);
*desBmpData = (unsigned char*)malloc(sizeof(unsigned char) * desBmpInfoHeader->biSizeImage);
double dX = -0.5 * desBmpInfoHeader->biWidth * dCos - 0.5 * desBmpInfoHeader->biHeight * dSin + 0.5 * srcBmpInfoHeader->biWidth;
double dY = 0.5 * desBmpInfoHeader->biWidth * dSin - 0.5 * desBmpInfoHeader->biHeight * dCos + 0.5 * srcBmpInfoHeader->biWidth;
int x = 0;
int y = 0;
for (int h = 0; h < desBmpInfoHeader->biHeight; h++){
for (int w = 0; w < desBmpInfoHeader->biWidth; w++){
x = (int)(w * dCos + h * dSin + dX + 0.5);//源图像像素点-横坐标
y = (int)(-w *dSin + h *dCos + dY + 0.5);//源图像像素点-纵坐标
if (x == srcBmpInfoHeader->biWidth){
x--;
}
if (y == srcBmpInfoHeader->biHeight){
y--;
}
if (x >= 0 && x < srcBmpInfoHeader->biWidth && y >= 0 && y < srcBmpInfoHeader->biHeight){
memcpy((*desBmpData) + h*desBmpInfoHeader->biWidth * 4 + w * 4, srcBmpData + y*srcBmpInfoHeader->biWidth * 4 + x * 4, 4);
}
}
}
}
void ZoomBmp(BMPFILEHEADER* srcBmpFileHeader, BMPINFOHEADER* srcBmpInfoHeader, BMPFILEHEADER* desBmpFileHeader, BMPINFOHEADER* desBmpInfoHeader,
unsigned char* srcBmpData, unsigned char** desBmpData /*, int zmHeight, int zmWidth, , double dxRate, double dyRate*/){
double dxRate, dyRate;
printf("\n请输入缩放的比例:横轴纵轴\n");
scanf("%lf %lf", &dxRate, &dyRate); getchar();
计算压缩比
//double dxRate = 0.0, dyRate = 0.0;
//复制文件头、文件信息头相关信息
*desBmpFileHeader = *srcBmpFileHeader;
*desBmpInfoHeader = *srcBmpInfoHeader;
//注意要修改 发生了变化的 文件头、文件信息头的相关信息
//计算压缩后的图像宽度、高度
desBmpInfoHeader->biWidth = srcBmpInfoHeader->biWidth * dxRate;
desBmpInfoHeader->biHeight = srcBmpInfoHeader->biHeight * dyRate;
//desBmpInfoHeader->biCompression = 0;
//计算缩放后的图像数据字节数,获取缩放后的图像大小
unsigned long dwSize = desBmpInfoHeader->biHeight * desBmpInfoHeader->biWidth * 4;//缩放后的图像大小
*desBmpData = (unsigned char*)malloc(sizeof(unsigned char) * dwSize);
memset(*desBmpData, 255, dwSize);
unsigned char* tempBmpData = *desBmpData;
unsigned char* pSrcData = srcBmpData;
int nx = 0, ny = 0;//源位图像素点的纵横坐标
//将源位图数据按比例缩放后复制到新位图数据中去
for (int i = 0; i < desBmpInfoHeader->biHeight; i++){
ny = (int)(i / dyRate + 0.5);
if (ny >= srcBmpInfoHeader->biHeight){
ny--;
}
for (int j = 0; j < desBmpInfoHeader->biWidth; j++){
nx = (int)(j / dxRate + 0.5);
if (nx >= srcBmpInfoHeader->biWidth){
nx--;
}
pSrcData = srcBmpData + (srcBmpInfoHeader->biWidth) * ny * 4 + nx * 4;
memcpy(tempBmpData, pSrcData, 4);
tempBmpData += 4;
}
}
}
void(*bbb[])(BMPFILEHEADER* srcBmpFileHeader, BMPINFOHEADER* srcBmpInfoHeader, BMPFILEHEADER* desBmpFileHeader, BMPINFOHEADER* desBmpInfoHeader,
unsigned char * srcBmpData, unsigned char** desBmpData) = { RotateBmp, ZoomBmp };//函数指针
void start(){
char path[15];
printf("请输入要旋转的图片名称:\n");
scanf("%s", path); getchar();
OnLoad(path, &srcBmpFileHeader, &srcBmpInfoHeader, &srcBmpData);
printf("\n选择要处理的类型:\n");
printf("0-旋转图片\n");
printf("1-缩放图片\n");
int choice;
printf("请选择:\n");
scanf("%d", &choice); getchar();
bbb[choice](&srcBmpFileHeader, &srcBmpInfoHeader, &desBmpFileHeader, &desBmpInfoHeader, srcBmpData, &desBmpData);
char savePath[15];
printf("\n请输入要保存的名称:\n");
scanf("%s", savePath); getchar();
WriteData(savePath, &desBmpFileHeader, &desBmpInfoHeader, desBmpData);
}
// writeBmpDlg.cpp : implementation file
//
#include "stdafx.h"
#include "writeBmp.h"
#include "writeBmpDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// 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()
/
// CWriteBmpDlg dialog
CWriteBmpDlg::CWriteBmpDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWriteBmpDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CWriteBmpDlg)
m_d = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CWriteBmpDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWriteBmpDlg)
DDX_Text(pDX, IDC_EDIT1, m_d);
DDV_MinMaxInt(pDX, m_d, -360, 360);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CWriteBmpDlg, CDialog)
//{{AFX_MSG_MAP(CWriteBmpDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
ON_BN_CLICKED(IDC_BUTTON4, OnButton4)
ON_BN_CLICKED(IDC_BUTTON5, OnButton5)
ON_BN_CLICKED(IDC_BUTTON6, OnButton6)
ON_BN_CLICKED(IDC_BUTTON7, OnButton7)
ON_BN_CLICKED(IDC_BUTTON8, OnButton8)
ON_BN_CLICKED(IDC_BUTTON9, OnButton9)
ON_BN_CLICKED(IDC_BUTTON10, OnButton10)
ON_BN_CLICKED(IDC_BUTTON11, OnButton11)
ON_BN_CLICKED(IDC_BUTTON12, OnButton12)
ON_BN_CLICKED(IDC_BUTTON13, OnButton13)
ON_BN_CLICKED(IDC_BUTTON14, OnButton14)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CWriteBmpDlg message handlers
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
BOOL CWriteBmpDlg::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
/*
FILE *fp;
fp = fopen("000.bmp","rb+");
fread(&bf,sizeof(bf),1,fp);//借用已有的bmp头文件格式
fread(&bi,sizeof(bi),1,fp);//可以详细了解这个两个结构
fclose(fp);
//*/
m_d = 30;
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CWriteBmpDlg::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 CWriteBmpDlg::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();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CWriteBmpDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
unsigned char buf[640*480*3];//bmp数据buf
unsigned char gray;
int hight,width;
unsigned char bmpHeader[54]=
{0x42,0x4d,0x38,0x10,0x0e,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x80,0x02,0x00,0x00,0xe0,0x01,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00,
0x00,0x00,0x02,0x10,0x0e,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00
};
void CWriteBmpDlg::OnButton1()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造1x1竖线数据
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(width%2 == 0)
{
gray = 0x00;//白
}
else
{
gray = 0xff;//黑
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("1x1_竖线.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::showbmp()
{
CWindowDC dc(this);
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
BYTE b = buf[(hight*640+width)*3 + 0];
BYTE g = buf[(hight*640+width)*3 + 1];
BYTE r = buf[(hight*640+width)*3 + 2];
dc.SetPixel(width+50,hight+150,RGB(r,g,b));
}
}
}
void CWriteBmpDlg::OnButton2()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造4x4竖线数据
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(width%4 == 0 || width%4 == 1)
{
gray = 0x00;//白
}
else
{
gray = 0xff;//黑
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("2x2_竖线.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::OnButton3()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造4x4竖线数据
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(width%8 == 0 || width%8 == 1||width%8 == 2 || width%8 == 3)
{
gray = 0x00;//白
}
else
{
gray = 0xff;//黑
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("4x4_竖线.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::OnButton4()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造1x1横线数据
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(hight%2 == 0)
{
gray = 0x00;//白
}
else
{
gray = 0xff;//黑
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("1x1_横线.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::OnButton5()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造2x2横线数据
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(hight%4 == 0 || hight%4 == 1)
{
gray = 0x00;//白
}
else
{
gray = 0xff;//黑
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("2x2_横线.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::OnButton6()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造4x4横线数据
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(hight%8 == 0 || hight%8 == 1||hight%8 == 2 || hight%8 == 3)
{
gray = 0x00;//白
}
else
{
gray = 0xff;//黑
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("4x4_横线.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::OnButton7()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造黑白四分屏
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(width<320 )
{
if(hight<240)
{
gray = 0x00;//白
}
else
{
gray = 0xff;//白
}
}
else
{
if(hight<240)
{
gray = 0xff;//白
}
else
{
gray = 0x00;//白
}
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("黑白四分屏.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::OnButton8()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造灰度四分屏
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(width<320 )
{
if(hight<240)
{
gray = 0xD0;//
}
else
{
gray = 0xA0;//
}
}
else
{
if(hight<240)
{
gray = 0x80;//
}
else
{
gray = 0x40;//
}
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("灰度四分屏.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::OnButton9()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造彩色四分屏
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(width<320 )
{
if(hight<240)
{
buf[(hight*640+width)*3 + 0]= 0xff;//b
buf[(hight*640+width)*3 + 1]= 0;//g
buf[(hight*640+width)*3 + 2]= 0;//r
}
else
{
buf[(hight*640+width)*3 + 0]= 0x00;//b
buf[(hight*640+width)*3 + 1]= 0xff;//g
buf[(hight*640+width)*3 + 2]= 0;//r
}
}
else
{
if(hight<240)
{
buf[(hight*640+width)*3 + 0]= 0;//b
buf[(hight*640+width)*3 + 1]= 0;//g
buf[(hight*640+width)*3 + 2]= 0xff;//r
}
else
{
buf[(hight*640+width)*3 + 0]= 0;//b
buf[(hight*640+width)*3 + 1]= 0xff;//g
buf[(hight*640+width)*3 + 2]= 0xff;//r
}
}
}
}
//保存bmp文件
fp = fopen("彩色四分屏.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
#include <math.h>
int round(float f)
{
if ((int)f+0.5>f)
return (int)f;
else
return (int)f + 1;
}
#define CV_PI 3.1415926
void CWriteBmpDlg::OnButton10()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
///*
CString pathName,tmp;
TCHAR szFilters[]= _T("MyType Files (*.bmp)|*.my|All Files (*.*)|*.*||");
CFileDialog fileDlg(TRUE, _T("bmp"), _T("*.bmp"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);
if(fileDlg.DoModal() == IDOK)
{
pathName = fileDlg.GetPathName();
}
else
{
MessageBox("重新选择图片");
return;
}
//*/
FILE *fp = fopen(pathName, "rb");
if (fp == 0)
{
printf("文件打开失败\n");
return ;
}
BITMAPFILEHEADER fileHead;
BITMAPINFOHEADER infoHead;
fread(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp);
fread(&infoHead, sizeof(BITMAPINFOHEADER), 1, fp);
int width = infoHead.biWidth;
int height = infoHead.biHeight;
int biCount = infoHead.biBitCount;
int lineByte = (width*biCount / 8 + 3) / 4 * 4;
// RGBQUAD *pColorTable;
// pColorTable = new RGBQUAD[256];
// fread(pColorTable, sizeof(RGBQUAD), 256, fp);
unsigned char *pBmpBufSrc,*pBmpBufDst;
pBmpBufSrc = new unsigned char[lineByte*height];
fread(pBmpBufSrc, lineByte*height, 1, fp);//640*480*3
fclose(fp);
//显示原始图像到窗口
//
CWindowDC dc(this);
for(int i=0;i<height;i++)
{
for(int k=0;k<width;k++)
{
BYTE b = pBmpBufSrc[(i*width+k)*3 + 0];
BYTE g = pBmpBufSrc[(i*width+k)*3 + 1];
BYTE r = pBmpBufSrc[(i*width+k)*3 + 2];
dc.SetPixel(k+50,height-i+150,RGB(r,g,b));
}
}//*/
///
Sleep(1000);
double angle=m_d;//旋转度数
double sita = angle*CV_PI / 180;
double a = (width - 1) / 2;//中心值
double b = (height - 1) / 2;
double x1 = -a*cos(sita) - b*sin(sita);//第2象限顶点
double y1 = -a*sin(sita) + b*cos(sita);
double x2 = a*cos(sita) - b*sin(sita);//第1象限
double y2 = a*sin(sita) + b*cos(sita);
double x3 = a*cos(sita) + b*sin(sita);//第4象限
double y3 = a*sin(sita) - b*cos(sita);
double x4 = -a*cos(sita) + b*sin(sita);//第3象限
double y4 = -a*sin(sita) - b*cos(sita);
int w1 = round(max(abs(x1 - x3), abs(x2 - x4)));//旋转后的宽度,高度
int h1 = round(max(abs(y1 - y3), abs(y2 - y4)));//取最大值
double c = (w1 - 1) / 2;//旋转后的中心
double d = (h1 - 1) / 2;
double f1 = -c*cos(sita) + d*sin(sita) + a;
double f2 = -c*sin(sita) - d*cos(sita) + b;
int lineByte1 = (w1*biCount / 8 + 3) / 4 * 4;
// int rgbData;
pBmpBufDst = new unsigned char[lineByte1*h1];
初始化目标图像buf
for ( i = 0; i < h1; ++i)
{
for (int j = 0; j < w1; ++j)
{
// unsigned char *p;
// p = (unsigned char *)(pBmpBufDst + i*lineByte1 + j);
// (*p++) = 255;(*p++) = 255;(*p++) = 255;
//rgb模式
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3+0) = 0xAA;
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3+1) = 0xAA;
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3+2) = 0xAA;
}
}
unsigned char *p1, *p2;
for ( i = 0; i < h1; ++i)
{
for (int j = 0; j < w1; ++j)
{
int x = round(j*cos(sita) - i*sin(sita) + f1); //(i,j)为旋转后的坐标(0,0),计算出在原图的坐标(x,y)
int y = round(j*sin(sita) + i*cos(sita) + f2);
if (x>0 && x<width && y>0 && y < height) //如果(x,y)落入原图640*480区间,赋颜色值
{
p1 = (unsigned char *)(pBmpBufDst + i*lineByte1 + j*3); // 新图像
p2 = (unsigned char *)(pBmpBufSrc + y*lineByte + x*3); // 原图像
// (*p1) = (*p2);
memcpy(p1,p2,3);
}
}
continue;
}
tmp.Format("-旋转%d度.bmp",m_d);
pathName += tmp;
char *DstName = "rotate.bmp";
FILE *fpo = fopen(pathName, "wb");
if (fpo == 0)
return ;
int colorTableSize = 0;
if (biCount == 8)
colorTableSize = 1024;
BITMAPFILEHEADER dstFileHead;
dstFileHead.bfOffBits = 14 + 40 + colorTableSize;
dstFileHead.bfReserved1 = 0;
dstFileHead.bfReserved2 = 0;
dstFileHead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTableSize + lineByte1*h1;
dstFileHead.bfType = 0x4D42;
fwrite(&dstFileHead, sizeof(dstFileHead), 1, fpo);
BITMAPINFOHEADER dstInfoHead;
dstInfoHead.biBitCount = biCount;
dstInfoHead.biClrImportant = 0;
dstInfoHead.biClrUsed = 0;
dstInfoHead.biCompression = 0;
dstInfoHead.biHeight = h1;
dstInfoHead.biPlanes = 1;
dstInfoHead.biSize = 40;
dstInfoHead.biSizeImage = lineByte1*h1;
dstInfoHead.biWidth = w1;
dstInfoHead.biXPelsPerMeter = 0;
dstInfoHead.biYPelsPerMeter = 0;
fwrite(&dstInfoHead, sizeof(BITMAPINFOHEADER), 1, fpo);
// fwrite(pColorTable, sizeof(RGBQUAD), 256, fpo);
fwrite(pBmpBufDst, lineByte1*h1, 1, fpo);
fclose(fpo);
//显示原始图像到窗口
//
// CWindowDC dc(this);
for(hight=0;hight<h1;hight++)
{
for(width=0;width<w1;width++)
{
BYTE b = pBmpBufDst[lineByte1*hight + 3*width + 0];
BYTE g = pBmpBufDst[lineByte1*hight + 3*width + 1];
BYTE r = pBmpBufDst[lineByte1*hight + 3*width + 2];
dc.SetPixel(width+50,h1-hight+150,RGB(r,g,b));
}
}
///
}
void CWriteBmpDlg::OnButton11()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造1x1横线数据
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(hight == 240 || width==320)
{
gray = 0x00;//黑
}
else
{
gray = 0xff;//白
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("十字线.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::OnButton12()
{
// TODO: Add your control notification handler code here
FILE *fp;
//构造1x1横线数据
for(hight=0;hight<480;hight++)
{
for(width=0;width<640;width++)
{
if(width==320)
{
gray = 0x00;//黑
}
else
{
gray = 0xff;//白
}
buf[(hight*640+width)*3 + 0]= gray;//b
buf[(hight*640+width)*3 + 1]= gray;//g
buf[(hight*640+width)*3 + 2]= gray;//r
}
}
//保存bmp文件
fp = fopen("单竖线.bmp","wb+");
// fwrite(&bf,sizeof(bf),1,fp);
// fwrite(&bi,sizeof(bi),1,fp);
fwrite(bmpHeader,54,1,fp);//直接写bmp头
fwrite(buf,640*480*3,1,fp);
fclose(fp);
//显示到窗口
showbmp();
}
void CWriteBmpDlg::OnButton13()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
int width = 640;//infoHead.biWidth;
int height = 480;//infoHead.biHeight;
int biCount = 24;//infoHead.biBitCount;
// int lineByte = (width*biCount / 8 + 3) / 4 * 4;
// RGBQUAD *pColorTable;
// pColorTable = new RGBQUAD[256];
// fread(pColorTable, sizeof(RGBQUAD), 256, fp);
unsigned char *pBmpBufSrc,*pBmpBufDst;
// pBmpBufSrc = new unsigned char[lineByte*height];
// fread(pBmpBufSrc, lineByte*height, 1, fp);//640*480*3
// fclose(fp);
double angle=m_d;//旋转度数
double sita = angle*CV_PI / 180;
double a = (width - 1) / 2;//中心值
double b = (height - 1) / 2;
double x1 = -a*cos(sita) - b*sin(sita);//第2象限顶点
double y1 = -a*sin(sita) + b*cos(sita);
double x2 = a*cos(sita) - b*sin(sita);//第1象限
double y2 = a*sin(sita) + b*cos(sita);
double x3 = a*cos(sita) + b*sin(sita);//第4象限
double y3 = a*sin(sita) - b*cos(sita);
double x4 = -a*cos(sita) + b*sin(sita);//第3象限
double y4 = -a*sin(sita) - b*cos(sita);
int w1 = round(max(abs(x1 - x3), abs(x2 - x4)));//旋转后的宽度,高度
int h1 = round(max(abs(y1 - y3), abs(y2 - y4)));//取最大值
//(791,732)
double c = (w1 - 1) / 2;//旋转后的中心
double d = (h1 - 1) / 2;//(395,365)
double f1 = -c*cos(sita) + d*sin(sita) + a;//159.4
double f2 = -c*sin(sita) - d*cos(sita) + b;//-274.6
int lineByte1 = (w1*biCount / 8 + 3) / 4 * 4;
pBmpBufDst = new unsigned char[lineByte1*h1];
初始化目标图像buf
for (int i = 0; i < h1; ++i)
{
for (int j = 0; j < w1; ++j)
{
// unsigned char *p;
// p = (unsigned char *)(pBmpBufDst + i*lineByte1 + j);
// (*p++) = 255;(*p++) = 255;(*p++) = 255;
//rgb模式
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3+0) = 0xAA;
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3+1) = 0xAA;
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3+2) = 0xAA;
}
}
for ( i = 0; i < h1; ++i)
{
for (int j = 0; j < w1; ++j)
{
int x = round(j*cos(sita) - i*sin(sita) + f1); //(i,j)为旋转后的坐标(0,0),计算出在原图的坐标(x,y)
int y = round(j*sin(sita) + i*cos(sita) + f2);//(0,0)-->(159,-274)
int y2=0;
if (x>0 && x<width && y>0 && y < height) //如果(x,y)落入原图640*480区间,赋颜色值
{//(551,0)-->(637,1)
unsigned char *p1, *p2,R;
p1 = (unsigned char *)(pBmpBufDst + i*lineByte1 + j*3); // 新图像
// p2 = (unsigned char *)(pBmpBufSrc + y*lineByte + x*3); // 原图像
// (*p1) = (*p2);
// memcpy(p1,p2,3);
R= *(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3 + 2) ;
if(x==320)
{
if(R==0xAA)
{
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3 + 0) = 0x00;
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3 + 1) = 0x00;
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3 + 2) = 0x00;
}
#if 1
y2 = round(j*tan((90-m_d)*1.0/180*3.1415926));
y2 = abs(y2)-312;
if(y2<h1)
{
*(unsigned char *)(pBmpBufDst + y2*lineByte1 + j*3 + 0) = 0x00;
*(unsigned char *)(pBmpBufDst + y2*lineByte1 + j*3 + 1) = 0x00;
*(unsigned char *)(pBmpBufDst + y2*lineByte1 + j*3 + 2) = 0xFF;
}
#endif
}
else
{
if(R==0xAA)
{
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3 + 0) = 0xf0;
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3 + 1) = 0xf0;
*(unsigned char *)(pBmpBufDst + i*lineByte1 + j*3 + 2) = 0xf0;
}
}
}
}
continue;
}
CString str;
str.Format("自划线旋转%d度.bmp",m_d);
// pathName += tmp;
// char *DstName = "rotate.bmp";
FILE *fpo = fopen(str, "wb");
if (fpo == 0)
return ;
int colorTableSize = 0;
if (biCount == 8)
colorTableSize = 1024;
BITMAPFILEHEADER dstFileHead;
dstFileHead.bfOffBits = 14 + 40 + colorTableSize;
dstFileHead.bfReserved1 = 0;
dstFileHead.bfReserved2 = 0;
dstFileHead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTableSize + lineByte1*h1;
dstFileHead.bfType = 0x4D42;
fwrite(&dstFileHead, sizeof(dstFileHead), 1, fpo);
BITMAPINFOHEADER dstInfoHead;
dstInfoHead.biBitCount = biCount;
dstInfoHead.biClrImportant = 0;
dstInfoHead.biClrUsed = 0;
dstInfoHead.biCompression = 0;
dstInfoHead.biHeight = h1;
dstInfoHead.biPlanes = 1;
dstInfoHead.biSize = 40;
dstInfoHead.biSizeImage = lineByte1*h1;
dstInfoHead.biWidth = w1;
dstInfoHead.biXPelsPerMeter = 0;
dstInfoHead.biYPelsPerMeter = 0;
fwrite(&dstInfoHead, sizeof(BITMAPINFOHEADER), 1, fpo);
// fwrite(pColorTable, sizeof(RGBQUAD), 256, fpo);
fwrite(pBmpBufDst, lineByte1*h1, 1, fpo);
fclose(fpo);
//显示原始图像到窗口
//
CWindowDC dc(this);
for(hight=0;hight<h1;hight++)
{
for(width=0;width<w1;width++)
{
BYTE b = pBmpBufDst[lineByte1*hight + 3*width + 0];
BYTE g = pBmpBufDst[lineByte1*hight + 3*width + 1];
BYTE r = pBmpBufDst[lineByte1*hight + 3*width + 2];
dc.SetPixel(width+50,h1-hight+150,RGB(r,g,b));
}
}
///
}
float a0,a1,a2;
int x[50],y[50];
void deal()//采用克莱默法则求解方程
{
int i,n=50,select=1;
float temp,temp0,temp1,temp2;
float sy=0,sx=0,sxx=0,syy=0,sxy=0,sxxy=0,sxxx=0,sxxxx=0;//定义相关变量
for(i=0;i<n;i++)
{
sx+=x[i];//计算xi的和
sy+=y[i];//计算yi的和
sxx+=x[i]*x[i];//计算xi的平方的和
sxxx+=pow(x[i],3);//计算xi的立方的和
sxxxx+=pow(x[i],4);//计算xi的4次方的和
sxy+=x[i]*y[i];//计算xi乘yi的的和
sxxy+=x[i]*x[i]*y[i];//计算xi平方乘yi的和
}
temp=n*sxx-sx*sx;//方程的系数行列式
temp0=sy*sxx-sx*sxy;
temp1=n*sxy-sy*sx;
a0=temp0/temp;
a1=temp1/temp;
if(select==1)
{
printf("经最小二乘法拟合得到的一元线性方程为:\n");
printf("f(x)=%3.3fx+%3.3f\n",a1,a0);
// system("pause");
return;
}
temp=n*(sxx*sxxxx-sxxx*sxxx)-sx*(sx*sxxxx-sxx*sxxx)//方程的系数行列式
+sxx*(sx*sxxx-sxx*sxx);
temp0=sy*(sxx*sxxxx-sxxx*sxxx)-sxy*(sx*sxxxx-sxx*sxxx)
+sxxy*(sx*sxxx-sxx*sxx);
temp1=n*(sxy*sxxxx-sxxy*sxxx)-sx*(sy*sxxxx-sxx*sxxy)
+sxx*(sy*sxxx-sxy*sxx);
temp2=n*(sxx*sxxy-sxy*sxxx)-sx*(sx*sxxy-sy*sxxx)
+sxx*(sx*sxy-sy*sxx);
a0=temp0/temp;
a1=temp1/temp;
a2=temp2/temp;
if(select==2)
{
printf("经最小二乘法拟合得到的二次近似方程为:\n");
printf("f(x)=%3.3fx2+%3.3fx+%3.3f\n",a2,a1,a0);
// system("pause");
}
}
void CWriteBmpDlg::OnButton14()
{
// TODO: Add your control notification handler code here
CString pathName,tmp;
TCHAR szFilters[]= _T("MyType Files (*.bmp)|*.my|All Files (*.*)|*.*||");
CFileDialog fileDlg(TRUE, _T("bmp"), _T("*.bmp"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);
if(fileDlg.DoModal() == IDOK)
{
pathName = fileDlg.GetPathName();
}
else
{
MessageBox("重新选择图片");
return;
}
CPoint blackPoint[1000*100];
FILE *fp = fopen(pathName, "rb");
if (fp == 0)
{
printf("文件打开失败\n");
return ;
}
BITMAPFILEHEADER fileHead;
BITMAPINFOHEADER infoHead;
fread(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp);
fread(&infoHead, sizeof(BITMAPINFOHEADER), 1, fp);
int width = infoHead.biWidth;
int height = infoHead.biHeight;
int biCount = infoHead.biBitCount;
int lineByte = (width*biCount / 8 + 3) / 4 * 4;
// RGBQUAD *pColorTable;
// pColorTable = new RGBQUAD[256];
// fread(pColorTable, sizeof(RGBQUAD), 256, fp);
unsigned char *pBmpBufSrc,*pBmpBufDst;
pBmpBufSrc = new unsigned char[lineByte*height];
fread(pBmpBufSrc, lineByte*height, 1, fp);//640*480*3
fclose(fp);
int pointCnt=0,flag=0;;
for(int i=0;i<height;i++)
{
flag=0;
for(int j=0;j<width;j++)
{
BYTE b = pBmpBufSrc[(i*width+j)*3 + 0];
BYTE g = pBmpBufSrc[(i*width+j)*3 + 1];
BYTE r = pBmpBufSrc[(i*width+j)*3 + 2];
b=b+g+r;
if(b==0 && flag==0)
{
// if(i==(height/2+50) || i==(height/2-50))
{
flag=1;
blackPoint[pointCnt].x=j;
blackPoint[pointCnt++].y=i;
}
}
}
}
float pp[4]={0};
int num1,num2;
num1=num2=0;
/* for(int k=0;k<(pointCnt/2*2);k++)
{
if(k<pointCnt/2)
{
pp[0] += blackPoint[k].x*1.0;
pp[1] += blackPoint[k].y*1.0;
num1++;
}
else
{
pp[2] += blackPoint[k].x*1.0;
pp[3] += blackPoint[k].y*1.0;
num2++;
}
}
pp[0] = pp[0]/num1;
pp[1] = pp[1]/num1;
pp[2] = pp[2]/num2;
pp[3] = pp[3]/num2;
*/
for(i=0;i<50;i++)
{
x[i] = blackPoint[100+i].x;
y[i] = blackPoint[100+i].y;
}
deal();//采用克莱默法则求解方程
// printf("经最小二乘法拟合得到的一元线性方程为:\n");
// printf("f(x)=%3.3fx+%3.3f\n",a1,a0);
tmp.Format("经最小二乘法拟合得到的一元线性方程为:f(x)=%3.3fx+%3.3f",a1,a0);
MessageBox(tmp);
}