我必须为学者目的进行OCR。 我不知道我是否可以在SDL中使用嵌入式旋转功能,所以我已经编写了一个基本的旋转功能。 它似乎工作,但我有一些问题:它只适用于一些图像,当它工作时,新的图像有点混乱。例如:
旋转前的图像:
60度旋转后的图像:
这是我的代码:
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <math.h>
#include "image.h"
double deg_to_rad(int angle)
{
return (angle*0.017453292519943);
}
SDL_Surface *rotate(SDL_Surface *image, int angle)
{
/* Trigo */
double cosa = cos(deg_to_rad(angle));
double sina = sin(deg_to_rad(angle));
int wo = abs((image->w)*cosa + (image->h)*sina);
int ho = abs((image->h)*cosa + (image->w)*sina);
/* Création d'une nouvelle image */
SDL_Surface *new_img;
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
new_img = SDL_CreateRGBSurface(0,wo,ho,32, rmask, gmask, bmask, amask);
int center_x = image->w / 2;
int center_y = image->h / 2;
int new_center_x = wo/2;
int new_center_y = ho/2;
for (int x = 0; x < wo; x++)
{
for (int y = 0; y < ho; y++)
{
int xo = abs(cosa*(x - new_center_x) + sina*(y - new_center_y) + center_x);
int yo = abs((-1)*sina*(x - new_center_x) + cosa*(y - new_center_y) + center_y);
lockSurface(image);
lockSurface(new_img);
Uint8 r,g,b;
Uint32 pixel;
Uint32 color;
if (xo >= 0 && yo >= 0 && xo < image->w && yo < image->h
&& x >= 0 && x < wo && y >=0 && y < ho)
{
pixel = getPixel(image, xo, yo);
SDL_GetRGB(pixel, image->format, &r, &g, &b);
color = SDL_MapRGB(image->format, r, g, b);
setPixel(new_img, x, y, color);
}
unlockSurface(image);
unlockSurface(new_img);
}
}
return new_img;
}
我做错了什么?
答案 0 :(得分:0)
如果您将图像想象为像素的“网格”,则很清楚为什么您的函数会扭曲它 - 旋转网格不会将像素映射到像素,并且通过获取仅一个最接近像素的值进行预旋转并将其插入后旋转像素,你有点“切角”。您将需要使用区域映射或超级采样算法来避免您看到的那些视觉瑕疵 - 这意味着在第一种情况下考虑像素“形状”并将“像素方块”的部分混合在一起,如果这是有意义的?
"A Fast Algorithm for General Raster Rotation" by Alan W. Paeth中的图片(和代码!)值得多说。