【发布时间】:2017-04-01 19:17:43
【问题描述】:
我对 BMP 图像的这种愚蠢的旋转功能有一些严重的问题......我已经在 2 天前发布了同样的问题,我知道......但是没有人能让我理解这里发生了什么,并且我该如何解决这个问题。
编辑:该图像将仅旋转 90 度倍数。
此刻我正试图将此图像旋转 180 度
这是我的结果直到这一刻
这是我的代码:
#include <algorithm>
#include <fstream>
#include <math.h>
#include <vector>
#include <iostream>
using namespace std;
double PI = 3.141592653589793238462643383279;
struct BMP {
int width;
int height;
unsigned char header[54];
unsigned char *pixels;
int row_padded;
int size_padded;
};
void writeBMP(string filename, BMP image) {
string fileName = "Output Files\\" + filename;
FILE *out = fopen(fileName.c_str(), "wb");
fwrite(image.header, sizeof(unsigned char), 54, out);
unsigned char tmp;
for (int i = 0; i < image.height; i++) {
for (int j = 0; j < image.width * 3; j += 3) {
//Convert(B, G, R) to(R, G, B)
tmp = image.pixels[j];
image.pixels[j] = image.pixels[j + 2];
image.pixels[j + 2] = tmp;
}
}
fwrite(image.pixels, sizeof(unsigned char), image.size_padded, out);
fclose(out);
}
BMP readBMP(string filename) {
BMP image;
string fileName = "Input Files\\" + filename;
FILE *in = fopen(fileName.c_str(), "rb");
if (in == NULL)
throw "Argument Exception";
fread(image.header, sizeof(unsigned char), 54, in); // read the 54-byte header
// extract image height and width from header
image.width = *(int *) &image.header[18];
image.height = *(int *) &image.header[22];
image.row_padded = (image.width * 3 + 3) & (~3); // ok size of a single row rounded up to multiple of 4
image.size_padded = image.row_padded * image.height; // padded full size
image.pixels = new unsigned char[image.size_padded]; // yeah !
if (fread(image.pixels, sizeof(unsigned char), image.size_padded, in) == image.size_padded) {
unsigned char tmp;
for (int i = 0; i < image.height; i++) {
for (int j = 0; j < image.width * 3; j += 3) {
// Convert (B, G, R) to (R, G, B)
tmp = image.pixels[j];
image.pixels[j] = image.pixels[j + 2];
image.pixels[j + 2] = tmp;
}
}
} else {
cout << "Error: all bytes couldn't be read" << endl;
}
fclose(in);
return image;
}
BMP rotate(BMP image, double degree) {
BMP newImage = image;
unsigned char *pixels = new unsigned char[image.size_padded];
double radians = (degree * PI) / 180;
int sinf = (int) sin(radians);
int cosf = (int) cos(radians);
double x0 = 0.5 * (image.width - 1); // point to rotate about
double y0 = 0.5 * (image.height - 1); // center of image
// rotation
for (int x = 0; x < image.height; x++) {
for (int y = 0; y < image.width * 3; y += 3) {
long double a = x - x0;
long double b = y - y0;
int xx = (int) (+a * cosf - b * sinf + x0);
int yy = (int) (+a * sinf + b * cosf + y0);
if (xx >= 0 && xx < image.width && yy >= 0 && yy < image.height) {
pixels[(y * image.width + x) * 3 + 0] = image.pixels[(yy * image.width + xx) * 3 + 0];
pixels[(y * image.width + x) * 3 + 1] = image.pixels[(yy * image.width + xx) * 3 + 1];
pixels[(y * image.width + x) * 3 + 2] = image.pixels[(yy * image.width + xx) * 3 + 2];
}
}
}
newImage.pixels = pixels;
return newImage;
}
int main() {
BMP image = readBMP("Image.bmp");
image = rotate(image, 180);
writeBMP("Output.bmp", image);
return 0;
}
所以请大家,我求求你们...你们中的哪一个可以帮我解决这个愚蠢的问题,它几乎没有杀死我 2 天:/
谢谢
【问题讨论】:
-
嗯,你比以前走得更远了。在你得到彻底的垃圾之前。现在你有一些类似的东西。颜色偏移和错位的一个很可能的原因是在旋转函数中
y应该乘以row_padded,而不是height。想想看。但是像素地址的重复计算是重复的代码,给代码增加了很多混乱,使整体算法变得混乱,更容易隐藏错误。将其分解为一个独立的函数:给定 y 和 x 以及 BMP,返回一个指向像素的指针。 -
@SamVarshavchik 我不知道我在这里做错了什么,因为此代码在其他图像上具有功能,除了我需要...Here 你可以找到我需要的原始图像。你能帮我让这段代码工作吗?
标签: c++ image image-processing bitmap bitmapimage