Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么我在改变SDL_曲面的像素时会得到奇怪的人工制品?_C_Sdl 2_Sdl Image - Fatal编程技术网

C 为什么我在改变SDL_曲面的像素时会得到奇怪的人工制品?

C 为什么我在改变SDL_曲面的像素时会得到奇怪的人工制品?,c,sdl-2,sdl-image,C,Sdl 2,Sdl Image,因此,我试图编辑SDL_曲面的每个像素,以应用灰度缩放公式。但是当运行我的代码时,我得到的区域是整个屏幕的宽度和表面的高度 void grayscale32(Uint8*像素,SDL\u像素格式*格式,整数宽度,整数高度, 整数音高){ Uint32*targetPixel=NULL; Uint8 r、g、b、灰色; 对于(int y=0;y*节距

因此,我试图编辑
SDL_曲面的每个像素,以应用灰度缩放公式。但是当运行我的代码时,我得到的区域是整个屏幕的宽度和表面的高度

void grayscale32(Uint8*像素,SDL\u像素格式*格式,整数宽度,整数高度,
整数音高){
Uint32*targetPixel=NULL;
Uint8 r、g、b、灰色;
对于(int y=0;y*节距<高度*宽度*3;y++){
对于(int x=0;x

我想在
Uint8
Uint32
之间来回转换是字节的问题,但我不知道确切的原因。我尝试将
Uint8*像素
作为
Uint32*
传递,但没有修复它,导致分割错误。

您有垂直条带,每行排列整齐(与阶梯步进相比)。因此,我相信您使用的
3
是正确的(即每个像素为3个字节)

这可能是由一些因素造成的

行地址中可能有一个字节被关闭

您可能正在包装/截断像素颜色值(即,您需要饱和度数学)。也就是说,(例如)如果计算的灰度值为256,它将换行/截断为0

我认为有一种更简单的方法可以索引到像素阵列中

无论如何,这里有一些重构代码。它没有经过测试,但它应该给你一些东西看

我假设格式是RGB(3字节/像素)[vs RGBA(4字节/像素)],并且
pitch
是每行的字节数

因此,实际上,第二个存储没有获得原始的
R

看起来/看起来可能没问题,但我怀疑结果的灰度值有点不合适

这里有一个版本可以解决这个问题。如果R和B值似乎相反,则可能需要使用
-DALT=1
进行编译。尝试两种方法:有/没有

#include <SDL2/SDL.h>
typedef unsigned char Uint8;
typedef unsigned int Uint32;

#ifndef ALT
#define ALT     0
#endif

enum {
#if ALT
    OFF_R = 2,
    OFF_G = 1,
    OFF_B = 0,
#else
    OFF_R = 0,
    OFF_G = 1,
    OFF_B = 2,
#endif

    PIXBYTES = 3
};

static inline Uint8
grayof(Uint8 r, Uint8 g, Uint8 b)
{
    Uint8 gray;

#if ORIG
    gray = 0.21 * r + 0.72 * g + 0.07 * b;
#else
    Uint32 acc = 0;

    // use scaled integer arithmetic (vs. float)
    acc += 210 * (Uint32) r;
    acc += 720 * (Uint32) g;
    acc += 70 * (Uint32) b;
    acc /= 1000;

    // saturation math
    // (e.g.) prevent pixel value of 256 from wrapping to 1
#if SAT
    if (acc > 255)
        acc = 255;
#endif

    gray = acc;
#endif

    return gray;
}

void
grayscale32(Uint8 *pixels, SDL_PixelFormat *format,
    int width, int height, int pitch)
{
    Uint8 *byteptr;
    Uint8 *bytelim;
    Uint8 gray;

    for (int y = 0;  y < height;  ++y) {
        byteptr = &pixels[y * pitch];
        bytelim = &byteptr[width * PIXBYTES];
        for (;  byteptr < bytelim;  byteptr += PIXBYTES) {
            gray = grayof(byteptr[OFF_R], byteptr[OFF_G], byteptr[OFF_B]);
            byteptr[OFF_R] = gray;
            byteptr[OFF_G] = gray;
            byteptr[OFF_B] = gray;
        }
    }
}
#包括
typedef无符号字符Uint8;
typedef无符号整数Uint32;
#ifndef ALT
#定义ALT 0
#恩迪夫
枚举{
#如果ALT
OFF_R=2,
OFF_G=1,
OFF_B=0,
#否则
OFF_R=0,
OFF_G=1,
OFF_B=2,
#恩迪夫
像素字节=3
};
静态内联Uint8
格雷奥夫(Uint8 r、Uint8 g、Uint8 b)
{
Uint8灰色;
#如果原始
灰色=0.21*r+0.72*g+0.07*b;
#否则
Uint32 acc=0;
//使用缩放整数运算(与浮点运算相比)
acc+=210*(Uint32)r;
acc+=720*(Uint32)g;
acc+=70*(Uint32)b;
acc/=1000;
//饱和数学
//(例如)防止256像素值换行为1
#如果坐
如果(acc>255)
acc=255;
#恩迪夫
灰色=acc;
#恩迪夫
返回灰色;
}
无效的
灰度32(Uint8*像素,SDL_像素格式*格式,
整数宽度、整数高度、整数间距)
{
Uint8*byteptr;
Uint8*bytelim;
Uint8灰色;
对于(int y=0;y
您有垂直条带,每行排列整齐(与楼梯踏步相比)。因此,我相信您使用的
3
是正确的(即每个像素为3个字节)

这可能是由一些因素造成的

行地址中可能有一个字节被关闭

您可能正在包装/截断像素颜色值(即,您需要饱和度数学)。也就是说,(例如)如果计算的灰度值为256,它将换行/截断为0

我认为有一种更简单的方法可以索引到像素阵列中

无论如何,这里有一些重构代码。它没有经过测试,但它应该给你一些东西看

我假设格式是RGB(3字节/像素)[vs RGBA(4字节/像素)],并且
pitch
是每行的字节数

因此,实际上,第二个存储没有获得原始的
R

看起来/看起来可能没问题,但我怀疑结果的灰度值有点不合适

这里有一个版本可以解决这个问题。如果R和B值似乎相反,则可能需要使用
-DALT=1
进行编译。尝试两种方法:有/没有

#include <SDL2/SDL.h>
typedef unsigned char Uint8;
typedef unsigned int Uint32;

#ifndef ALT
#define ALT     0
#endif

enum {
#if ALT
    OFF_R = 2,
    OFF_G = 1,
    OFF_B = 0,
#else
    OFF_R = 0,
    OFF_G = 1,
    OFF_B = 2,
#endif

    PIXBYTES = 3
};

static inline Uint8
grayof(Uint8 r, Uint8 g, Uint8 b)
{
    Uint8 gray;

#if ORIG
    gray = 0.21 * r + 0.72 * g + 0.07 * b;
#else
    Uint32 acc = 0;

    // use scaled integer arithmetic (vs. float)
    acc += 210 * (Uint32) r;
    acc += 720 * (Uint32) g;
    acc += 70 * (Uint32) b;
    acc /= 1000;

    // saturation math
    // (e.g.) prevent pixel value of 256 from wrapping to 1
#if SAT
    if (acc > 255)
        acc = 255;
#endif

    gray = acc;
#endif

    return gray;
}

void
grayscale32(Uint8 *pixels, SDL_PixelFormat *format,
    int width, int height, int pitch)
{
    Uint8 *byteptr;
    Uint8 *bytelim;
    Uint8 gray;

    for (int y = 0;  y < height;  ++y) {
        byteptr = &pixels[y * pitch];
        bytelim = &byteptr[width * PIXBYTES];
        for (;  byteptr < bytelim;  byteptr += PIXBYTES) {
            gray = grayof(byteptr[OFF_R], byteptr[OFF_G], byteptr[OFF_B]);
            byteptr[OFF_R] = gray;
            byteptr[OFF_G] = gray;
            byteptr[OFF_B] = gray;
        }
    }
}
#包括
typedef无符号字符Uint8;
typedef无符号整数Uint32;
#ifndef ALT
#定义ALT 0
#恩迪夫
枚举{
#如果ALT
OFF_R=2,
OFF_G=1,
OFF_B=0,
#否则
OFF_R=0,
OFF_G=1,
OFF_B=2,
#恩迪夫
像素字节=3
};
静态内联Uint8
格雷奥夫(Uint8 r、Uint8 g、Uint8 b)
{
Uint8灰色;
#如果原始
灰色=0.21*r+0.72*g+0.07*b;
#否则
Uint32 acc=0;
//使用缩放整数运算(与浮点运算相比)
acc+=210*(Uint32)r;
acc+=720*(Uint32)g;
acc+=70*(Uint32)b;
acc/=1000;
//饱和数学
//(例如)防止256像素值换行为1
#如果坐
如果(acc>255)
acc=255;
#恩迪夫
灰色=acc;
#恩迪夫
返回灰色;
}
无效的
灰度32(Uint8*像素,SDL_像素格式*格式,
整数宽度、整数高度、整数间距)
{
Uint8*byteptr;
Uint8*bytelim;
Uint8灰色;
对于(int y=0;y
事实上,您的索引方法更简单,实际上解决了我的问题。我没有
Memory layout:
| 0       3       6       9
| R G B | R G B | R G B | R G B |

Store progression:
| 1 2 3 | 4
        | 1 2 3 | 4
                | 1 2 3 | 4
                        | 1 2 3 | 4
#include <SDL2/SDL.h>
typedef unsigned char Uint8;
typedef unsigned int Uint32;

#ifndef ALT
#define ALT     0
#endif

enum {
#if ALT
    OFF_R = 2,
    OFF_G = 1,
    OFF_B = 0,
#else
    OFF_R = 0,
    OFF_G = 1,
    OFF_B = 2,
#endif

    PIXBYTES = 3
};

static inline Uint8
grayof(Uint8 r, Uint8 g, Uint8 b)
{
    Uint8 gray;

#if ORIG
    gray = 0.21 * r + 0.72 * g + 0.07 * b;
#else
    Uint32 acc = 0;

    // use scaled integer arithmetic (vs. float)
    acc += 210 * (Uint32) r;
    acc += 720 * (Uint32) g;
    acc += 70 * (Uint32) b;
    acc /= 1000;

    // saturation math
    // (e.g.) prevent pixel value of 256 from wrapping to 1
#if SAT
    if (acc > 255)
        acc = 255;
#endif

    gray = acc;
#endif

    return gray;
}

void
grayscale32(Uint8 *pixels, SDL_PixelFormat *format,
    int width, int height, int pitch)
{
    Uint8 *byteptr;
    Uint8 *bytelim;
    Uint8 gray;

    for (int y = 0;  y < height;  ++y) {
        byteptr = &pixels[y * pitch];
        bytelim = &byteptr[width * PIXBYTES];
        for (;  byteptr < bytelim;  byteptr += PIXBYTES) {
            gray = grayof(byteptr[OFF_R], byteptr[OFF_G], byteptr[OFF_B]);
            byteptr[OFF_R] = gray;
            byteptr[OFF_G] = gray;
            byteptr[OFF_B] = gray;
        }
    }
}