1

出于学术目的,我必须进行 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;
}

我究竟做错了什么?

4

1 回答 1

1

如果您将图像想象为像素的“网格”,那么您的函数为什么会扭曲它就会很清楚 - 旋转该网格不会将像素映射到像素,并且只取一个最接近的像素预旋转的值并将其插入进入旋转后像素,您实际上是在“偷工减料”。您需要使用区域映射或超级采样算法来避免您看到的那些视觉伪影 - 这意味着在第一种情况下考虑像素“形状​​”并将“像素方块”的各个部分混合在一起,如果这有意义的话?

Alan W. Paeth 的“A Fast Algorithm for General Raster Rotation”中的图片(和代码!)值得一说。

于 2014-09-16T18:01:29.433 回答