C ++: повернуть изображение BMP

У меня есть серьезные проблемы с этой глупой функцией поворота изображения 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 дня почти даром: /

Спасибо

-1

Решение

Проверьте полный код:

#include <algorithm>
#include <fstream>
#include <math.h>
#include <vector>
#include <string>
#include <iostream>
#include <chrono>
//#include "operation_parser.h"
using namespace std;
using namespace std::chrono;

double PI = 3.141592653589793238462643383279;
struct BMP {
int width;
int height;
unsigned char header[54];
unsigned char *pixels;
int size;
int row_padded;
long long int size_padded;
};

void writeBMP(string filename, BMP image) {
string fileName = 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 = 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 rotate180Degree(BMP image, double degree) {
_ASSERTE(degree == 180.0);

BMP newImage = image;
unsigned char *pixels = new unsigned char[image.size_padded];

int H = image.height, W = image.width;
for (int x = 0; x < H; x++) {
for (int y = 0; y < W;y ++) {
pixels[(x * W + y) * 3 + 0] = image.pixels[((H - 1 - x) * W + (W - 1 - y)) * 3 + 0];
pixels[(x * W + y) * 3 + 1] = image.pixels[((H - 1 - x) * W + (W - 1 - y)) * 3 + 1];
pixels[(x * W + y) * 3 + 2] = image.pixels[((H - 1 - x) * W + (W - 1 - y)) * 3 + 2];
}
}

newImage.pixels = pixels;
return newImage;
}

int main() {
BMP image = readBMP("test.bmp");
image = rotate180Degree(image, 180);
writeBMP("Output.bmp", image);
return 0;
}

Если только 0,90,180,270 градусов, чтобы повернуть, вот пример поворота 180 градусов, измените его, если вы хотите сделать это с 0,90,270(ширина и высота изображения менять когда rotate_degree = 90 or 270):

BMP rotate180Degree(BMP image, double degree) {
_ASSERTE(degree == 180.0);

BMP newImage = image;
unsigned char *pixels = new unsigned char[image.size_padded];

int H = image.height, W = image.width;
for (int x = 0; x < H; x++) {
for (int y = 0; y < W;y ++) {
pixels[(x * W + y) * 3 + 0] = image.pixels[((H - 1 - x) * W + (W - 1 - y)) * 3 + 0];
pixels[(x * W + y) * 3 + 1] = image.pixels[((H - 1 - x) * W + (W - 1 - y)) * 3 + 1];
pixels[(x * W + y) * 3 + 2] = image.pixels[((H - 1 - x) * W + (W - 1 - y)) * 3 + 2];
}
}

newImage.pixels = pixels;
return newImage;
}
std::shared_ptr<CImage> OriginalImg = std::make_shared<CImage>();
OriginalImg->Load("test.png");

int W = OriginalImg->GetWidth(), H = OriginalImg->GetHeight();

std::shared_ptr<CImage> RotatedImg = std::make_shared<CImage>();
RotatedImg->Create(W, H, OriginalImg->GetBPP());

for (unsigned int x = 0; x < W; ++x)
{
for (unsigned int y = 0; y < H; ++y)
{
RotatedImg->SetPixel(x, y, OriginalImg->GetPixel(W - x - 1, H - y - 1));
}
}

RotatedImg->Save("rotatedImage.png");

Повернутое изображение

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector