C - 逐字节缩放(插值)

时间:2014-01-21 05:46:55

标签: c scaling interpolation linear

更新:现在代码正常,请参阅问题末尾的编辑

我正在编写一个简单的应用程序,它应该缩放给定图像并在屏幕上显示结果。图像加载,显示等是通过SDL实现的,但我仍然有缩放功能的问题 - 它会产生乱码。

我必须对24位图像进行操作,因此uint8_t转换和逐字节计算。

#include <stdint.h>
void blin(uint8_t* pixelsIn, uint8_t* pixelsOut, int w, int h, float scale)
{
    int index1, index2;
    int w2, h2;
    int i, j, k;
    float x, y;
    float t;
    int p1, p2;

    w2 = (int)(scale*w + 0.5);
    h2 = (int)(scale*h + 0.5);
    p1 = w*3;
    if(p1%4) p1 += (4-p1%4);
    p2 = w2*3;
    if(p2%4) p2 += (4-p2%4);
    for(i=0;i<h2;i++) //line
    {
        index2=i*p2;
        for(j=0;j<w2;j++) //column
        {
            x=((float)(j))/scale;
            index1=(int)(x) * 3;
            x-=(int)(x);
            y=((float)(i))/scale;
            index1+=(int)(y) * p1;
            y-=(int)(y);
            for(k=0;k<3;k++) //for color in R, G, B
            {
                t = (float)(pixelsIn[index1]) * (1.0-x)*(1.0-y);
                t += (float)(pixelsIn[index1+3]) * (x)*(1.0-y);
                t += (float)(pixelsIn[index1+p1]) * (1.0-x)*(y);
                t += (float)(pixelsIn[index1+p1+3]) * (x)*(y);
                pixelsOut[index2] = (uint8_t)(t);
                index1++;
                index2++;
            }
        }
    }
}

编辑:明显的错误,index2未归零,并且计算x而不乘以3(每像素字节数)。但是图像仍然没有正确缩放,这是scale = 1.0之前和之后(jpgs只是为了更快上传):

Edit2:第二个问题是SDL_Surface像素结构内部的4字节对齐。现在它就像一个魅力(代码在这里更新),虽然它只适用于24位图像 - 请参阅评论以获得最佳答案。

1 个答案:

答案 0 :(得分:0)

我认为这一行: -

index1=(int)(x);

应该是: -

index1=(int)(x)*3;

另外,不要假设步幅与width.sizeof(pixel)相同,一行上的第一个像素可能与word / dword / etc边界对齐,所以我将代码更改为: -

void blin(uint8_t* pixelsIn, uint8_t* pixelsOut, int w, int h, float scale, int input_stride, int output_stride)
{
    int index1, index2;
    int w2, h2;
    int i, j, k;
    float x, y;
    float t;

    w2=(int)(scale*w + 0.5);
    h2=(int)(scale*h + 0.5);
    index2=0;
    for(i=0;i<h2;i++) //line
    {
        int pixelindex2=index2;
        for(j=0;j<w2;j++) //column
        {
            x=((float)(j))/scale;
            index1=(int)(x)*3;
            x-=(int)(x);
            y=((float)(i))/scale;
            index1+=(int)(y) * input_stride;
            y-=(int)(y);
            for(k=0;k<3;k++) //for color in R, G, B
            {
                t = (float)(pixelsIn[index1]) * (1.0-x)*(1.0-y);
                t += (float)(pixelsIn[index1+3]) * (x)*(1.0-y);
                t += (float)(pixelsIn[index1+w*3]) * (1.0-x)*(y);
                t += (float)(pixelsIn[index1+w*3+3]) * (x)*(y);
                pixelsOut[pixelindex2] = (uint8_t)(t);
                index1++;
                pixelindex2++;
            }
        } //column
        index2+=output_stride;
    } //line
}

其中input_strideoutput_stride是连续行开头之间的字节数,可能与width * 3不同。

您可能还需要考虑将'3'常量变为变量,以便您可以处理不同的图像格式。