东南大学数字图像处理作业-C++原生实现(不调库)对BMP图像旋转和平移

本文介绍了如何在不使用库的情况下,利用C++原生代码处理BMP图像,包括图像的旋转和平移操作。文章分为三个部分:代码实现、实现效果展示以及难点解析,详细讨论了BMP图像的存储结构和矩阵变换在转化过程中的应用。
摘要由CSDN通过智能技术生成

1 代码

包含三个文件:把bmp.h、bmp.cpp、main.cpp
1.1 bmp.h

#pragma once
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;

//位图文件头定义
typedef struct  tagBITMAPFILEHEADER {
	//	WORD bfType;//单独读取,结构体中就不定义了
	DWORD bfSize;//文件大小
	WORD bfReserved1;//保留字
	WORD bfReserved2;//保留字
	DWORD bfOffBits;//从文件头到实际位图数据的偏移字节数
}BITMAPFILEHEADER;

//位图信息头定义
typedef struct tagBITMAPINFOHEADER {
	DWORD biSize;//信息头大小
	DWORD biWidth;//图像宽度
	DWORD biHeight;//图像高度
	WORD biPlanes;//位平面数,必须为1
	WORD biBitCount;//每像素位数
	DWORD  biCompression; //压缩类型
	DWORD  biSizeImage; //压缩图像大小字节数
	DWORD  biXPelsPerMeter; //水平分辨率
	DWORD  biYPelsPerMeter; //垂直分辨率
	DWORD  biClrUsed; //位图实际用到的色彩数
	DWORD  biClrImportant; //本位图中重要的色彩数
}BITMAPINFOHEADER; //位图信息头定义

//彩色图像的像素信息
typedef struct tagRgbImgData
{
	BYTE blue;
	BYTE green;
	BYTE red;
}DATA;

// 灰度图像的像素信息
typedef struct tagGrayBmpData
{
	BYTE gray;
}GRAYDATA;

// 调色板的结构定义,灰度图有256个调色板
typedef struct tagRGBQUAD {
	BYTE rgbBlue;    // 蓝色的亮度(值范围为0-255) 
	BYTE rgbGreen;   // 绿色的亮度(值范围为0-255) 
	BYTE rgbRed;     // 红色的亮度(值范围为0-255) 
	BYTE rgbReserved;// 保留,必须为0 
} RGBQUAD;

double xAfterRot(int x, int y, double theta, int cx, int cy);
double yAfterRot(int x, int y, double theta, int cx, int cy);

// 检查图片类型是不是BMP
int checkImgType(const char* filename);
// 彩色BMP图像读取操作
DATA* readRgbBmp(const char* filename, WORD* bfType, BITMAPFILEHEADER* strHead, BITMAPINFOHEADER* strInfo, int* h, int* mw, int* imgSize, int* cx, int* cy);
// 灰色BMP图像读取操作
GRAYDATA* readGrayBmp(const char* filename, WORD* bfType, BITMAPFILEHEADER* strHead, BITMAPINFOHEADER* strInfo, RGBQUAD* ipRGB, int* h, int* mw, int* imgSize, int* cx, int* cy);
int modifyWidth(int biWidth);
int getImageSize(int biWidth, int biHeight, int bitCount);
DATA* scale(const DATA* src, float x, float y, int mh, int mw, int imgSize, int cx, int cy, BITMAPFILEHEADER strHead, BITMAPINFOHEADER strInfo, WORD bfType);
GRAYDATA* scaleGray(const GRAYDATA* src, float x, float y, int mh, int mw, int imgSize, int cx, int cy, BITMAPFILEHEADER strHead, BITMAPINFOHEADER strInfo, WORD bfType, RGBQUAD* ipRGB);


DATA* rotation(const DATA* src, double theta, int mh, int mw, int imgSize, int cx, int cy, BITMAPFILEHEADER strHead, BITMAPINFOHEADER strInfo, WORD bfType);
GRAYDATA* rotationGray(const GRAYDATA* src, double theta, int mh, int mw,
	int imgSize, int cx, int cy, BITMAPFILEHEADER strHead, BITMAPINFOHEADER strInfo,WORD bfType, RGBQUAD* ipRGB);

1. 2 bmp.cpp

#include <cstdio>
#include <iostream>
#include <vector>
#include<algorithm>
#include <cmath>
#define PI acos(-1)
#include <cstdlib>
#include<exception>
#include<set>
#include "bmp.h"
using namespace std;

int checkImgType(const char* filename) {
	FILE* fpi = fopen(filename, "rb");
	WORD bfType;
	if (fpi == NULL) {
		cout << filename << " 文件未能找到" << endl;
		return 0;
	}
	else {
		fread(&bfType, 1, sizeof(WORD), fpi);
		if (0x4d42 != bfType) {
			cout << "Error: The file is not a bmp image!" << endl;
			return 0;
		}
	}
	return 1;
}


int modifyWidth(int biWidth) {
	if (biWidth % 4 == 0)
		return biWidth;
	return (biWidth / 4 + 1) * 4;
}

int getImageSize(int biWidth, int biHeight, int bitCount) {
	int bytePerPixel = bitCount / 8;
	int LineBytes = (biWidth * bytePerPixel + 3) / 4 * 4; //这个其实也相当于是每行的宽度,但是这里的宽度指的是字节数,而不是像素数
	return LineBytes * biWidth;
}

DATA * readRgbBmp(const char* filename, WORD * bfType, BITMAPFILEHEADER* strHead, BITMAPINFOHEADER* strInfo, int* h, int* mw, int* imgSize, int * cx, int* cy) {
	FILE* fpi = fopen(filename, "rb");
	fread(bfType, 1, sizeof(WORD), fpi);
	fread(strHead, 1, sizeof(tagBITMAPFILEHEADER), fpi);
	fread(strInfo, 1, sizeof(tagBITMAPINFOHEADER), fpi);
	*h = (*strInfo).biHeight;
	*mw = modifyWidth((*strInfo).biWidth);
	*imgSize = (*h) * (*mw);
	*cx = (*mw) / 2;
	*cy = (*h) / 2;
	DATA* imgData = new DATA[*imgSize];
	fread(imgData, 1, sizeof(DATA) * (*imgSize), fpi);
	return imgData;
}

GRAYDATA* readGrayBmp(const char* filename, WORD* bfType, BITMAPFILEHEADER* strHead, BITMAPINFOHEADER* strInfo, RGBQUAD
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值