C语言实现BMP图像90度顺时针旋转求助(附180度旋转代码)
BMP图像90度顺时针旋转的C语言实现
你的180度旋转代码逻辑是对的,核心通过new_i = height - 1 - j和new_j = width - 1 - i完成坐标双向翻转。但90度顺时针旋转需要处理图像尺寸互换和更复杂的坐标映射,同时要严格遵循BMP的行对齐规则,以下是完整实现方案:
关键差异说明
- 尺寸变化:旋转后图像宽高互换,原宽度
width变为新高度,原高度height变为新宽度 - 行对齐重计算:新图像的行字节数需根据新宽度重新计算(必须是4的倍数)
- 坐标映射:原图像中
(j行, i列)的像素,顺时针旋转90度后对应新图像的(i行, height-1-j列)
完整实现代码
// 假设header已正确读取,包含BMP文件头和信息头,width、height为原图像宽高 int orig_row_size = ((width * 3 + 3) / 4) * 4; uint8_t* pixels = (uint8_t*)malloc(height * orig_row_size); fread(pixels, sizeof(uint8_t), height * orig_row_size, input); // 计算旋转后的图像参数 uint32_t new_width = height; uint32_t new_height = width; int new_row_size = ((new_width * 3 + 3) / 4) * 4; uint8_t* rotatedPixels = (uint8_t*)malloc(new_height * new_row_size); // 逐个像素映射 for (uint32_t j = 0; j < height; ++j) { // j为原图像行索引(从上到下) for (uint32_t i = 0; i < width; ++i) { // i为原图像列索引(从左到右) // 定位原像素地址 uint8_t* orig_pixel = pixels + j * orig_row_size + i * 3; // 计算旋转后的像素位置 uint32_t new_row = i; uint32_t new_col = height - 1 - j; uint8_t* dest_pixel = rotatedPixels + new_row * new_row_size + new_col * 3; // 复制BGR三通道数据 dest_pixel[0] = orig_pixel[0]; dest_pixel[1] = orig_pixel[1]; dest_pixel[2] = orig_pixel[2]; } } // 更新BMP头信息(必须修改,否则图像无法正常显示) BITMAPINFOHEADER* info_header = (BITMAPINFOHEADER*)(header + sizeof(BITMAPFILEHEADER)); info_header->biWidth = new_width; info_header->biHeight = new_height; info_header->biSizeImage = new_height * new_row_size; BITMAPFILEHEADER* file_header = (BITMAPFILEHEADER*)header; file_header->bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + info_header->biSizeImage; // 写入旋转后的图像 fwrite(header, sizeof(uint8_t), 54, output); fwrite(rotatedPixels, sizeof(uint8_t), new_height * new_row_size, output); // 释放内存 free(pixels); free(rotatedPixels);
注意事项
- BMP头更新:必须修改信息头中的宽高、图像大小,以及文件头中的总文件大小,否则旋转后的图像无法被正确解析
- 行对齐规则:BMP要求每行字节数为4的整数倍,新图像的行大小必须重新计算,不能复用原行大小
- 存储顺序:BMP图像的行是从上到下存储的,坐标映射时需注意行索引的逆序处理
内容的提问来源于stack exchange,提问作者ms complaints
相关产品推荐
相关产品推荐

