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;
}
}
}