c - 在 C 中缩放 8 位灰度 RAW

标签 c image pixel

目前,我正在尝试将 320x200、8 位 RAW 图像缩放到用户指定的首选分辨率的任何大小。如果他们的分辨率是 320x200,它只是简单地使用 fread 直接读取数据来填充它,否则它会水平地加倍所有像素,产生一个 640x200 的图像。然而,这不是我想要做的,我想精确地缩放到 PIXX/PIXY 的值,即使它不是倍数。我该怎么做?

这是代码的重要部分:

FILE    *f;

int x,y;
int x1,y1;

int c;

char    *p;

f = dopen("art",name,"rb");
if (f == 0) GTFO("Unable to open title");

p = vpage;

if ((PIXX == 320) && (PIXY == 200))
{
    fread(vpage,320,200,f);
}
else
{
    for (y1 = 0; y1 < 200; y1++)
    {
        for (x1 = 0; x1 < 320; x1++)
        {
            c = getc(f);

            *p = c;
            *(p + 1) = c;
            p += 2;
        }
    }
}

fclose(f);

如果存在可以获取 fread 生成的图像并执行线性缩放的函数或库,则输出回 8 位原始格式会非常好。图像存储在 vpage 中。

编辑:这是我使用 Bresenham 算法的尝试,由于某种原因它会产生垃圾,但可以正确缩放垃圾,哈哈。

#include "imgscale.h"

void ScaleLine(unsigned char *Target, unsigned char *Source, int SrcWidth, int TgtWidth)
{
    int NumPixels = TgtWidth;
    int IntPart = SrcWidth / TgtWidth;
    int FractPart = SrcWidth % TgtWidth;
    int E = 0;
    while (NumPixels-- > 0)
    {
        *Target++ = *Source;
        Source += IntPart;

        E += FractPart;
        if (E >= TgtWidth)
        {
            E -= TgtWidth;
            Source++;
        } /* if */
    } /* while */
}

#define average(a, b)   (unsigned char)(( (int)(a) + (int)(b) ) >> 1)
void ScaleLineAvg(unsigned char *Target, unsigned char *Source, int SrcWidth, int TgtWidth)
{
    int NumPixels = TgtWidth;
    int Mid = TgtWidth / 2;
    int E = 0;
    char p;

    if (TgtWidth > SrcWidth)
    {
        NumPixels--;
    }

    while (NumPixels-- > 0)
    {
        p = *Source;

        if (E >= Mid)
        {
            p = average(p, *(Source+1));
        }

        *Target++ = p;
        E += SrcWidth;
        if (E >= TgtWidth)
        {
            E -= TgtWidth;
            Source++;
        } /* if */
    } /* while */

    if (TgtWidth > SrcWidth)
    {
        *Target = *Source;
    }
}

void ScaleRect(unsigned char *Target, unsigned char *Source, int SrcWidth, int SrcHeight, int TgtWidth, int TgtHeight)
{
    int NumPixels = TgtHeight;
    int IntPart = (SrcHeight / TgtHeight) * SrcWidth;
    int FractPart = SrcHeight % TgtHeight;
    int E = 0;
    char *PrevSource;
    while (NumPixels-- > 0)
    {
        if (Source == PrevSource)
        {
            memcpy(Target, Target-TgtWidth, TgtWidth*sizeof(*Target));
        }
        else
        {
            ScaleLine(Target, Source, SrcWidth, TgtWidth);
            PrevSource = Source;
        } /* if */

        Target += TgtWidth;
        Source += IntPart;
        E += FractPart;

        if (E >= TgtHeight)
        {
            E -= TgtHeight;
            Source += SrcWidth;
        } /* if */
    } /* while */
}

最佳答案

我设法找到了解决方案。我需要将图像加载到新的缓冲区中,而不是直接读取文件。

这段代码对我有用

    int i;
    FILE    *f;
    char *vpage2;

    f = dopen("art",name,"rb");
    if (f == 0) {
        char    text[80];

        sprintf(text,"Unable to open title: %s",name);
        GTFO(text);
    }

    vpage2 = malloc(PIXX*PIXY);

    fread(vpage2,320,200,f);

    ScaleRect(vpage, vpage2, 320, 200, PIXX, PIXY);

    fclose(f);

    for (i = 0; i < PIXX * PIXY; i++) {
        vpage[i] = lightTable[0][vpage[i]];
    }

关于c - 在 C 中缩放 8 位灰度 RAW,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31094488/

相关文章:

c - TEMP_FAILURE_RETRY 和 __USE_GNU

image - Windows Phone 8 和 AngularJs - ng-src 不工作?

javascript - 我怎样才能确保 .animate 在再次执行之前已经完成

java - Java 中的快速像素搜索

java - 如何知道图像每个像素是32位、24位、8位、1位

visual-c++ - 如何获取光标下的像素颜色?

将 char 数组中的内容转换为 C 中的十六进制(例如 : {'5' , 'A' } 到 0x5A)

c - 不要从 char palindrome[] 中获取输出

java - 如何使用引用 RGB 值对 RGB 值进行归一化

c - 'fopen' 将如何解释一个容量大于它包含的字符串的 'char[]'?