Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.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++ 如何纠正水平翻转功能以防止其改变图像';颜色_C++_C_Ruby - Fatal编程技术网

C++ 如何纠正水平翻转功能以防止其改变图像';颜色

C++ 如何纠正水平翻转功能以防止其改变图像';颜色,c++,c,ruby,C++,C,Ruby,h提供了一种垂直翻转图像的方法,效果良好。我试图实现一个水平翻转的镜子,但它改变了图像的颜色 在只有3种颜色的图片上,你可以得到蓝色、红色甚至是洋红色的图片,而不是它们的实际颜色。如果我们谈论JPEG或PNG图像,同样会得到同样奇怪的结果。奇怪的是,如果你垂直翻转同样的图像,它的颜色看起来很正常 我已经试过测试你在这里能找到的几乎所有函数,我提供给你的代码是唯一让我接近我实际目标的代码 // Function I've been trying to implement to enable Hor

h提供了一种垂直翻转图像的方法,效果良好。我试图实现一个水平翻转的镜子,但它改变了图像的颜色

在只有3种颜色的图片上,你可以得到蓝色、红色甚至是洋红色的图片,而不是它们的实际颜色。如果我们谈论JPEG或PNG图像,同样会得到同样奇怪的结果。奇怪的是,如果你垂直翻转同样的图像,它的颜色看起来很正常

我已经试过测试你在这里能找到的几乎所有函数,我提供给你的代码是唯一让我接近我实际目标的代码

// Function I've been trying to implement to enable Horizontal Flip
static void stbi_horizontal_flip(void *image, int w, int h, int bytes_per_pixel)
{
    size_t line_bytes = (size_t)w * bytes_per_pixel;
    stbi_uc temp[line_bytes];
    stbi_uc *bytes = (stbi_uc *)image;
    Debug() << line_bytes;
    for (int col = 0; col < h; col++) {
        stbi_uc *line = bytes + col * line_bytes;
        memcpy(&temp, line, line_bytes);
        for (int row = 0; row < line_bytes; row++) {
            line[row] = temp[line_bytes - row - bytes_per_pixel];
        }
    }
    stbi_horizontally_flip_on_load = false;
}
// stb_image's function for Vertical Flip
static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
{
    int row;
    size_t bytes_per_row = (size_t)w * bytes_per_pixel;
    stbi_uc temp[2048];
    stbi_uc *bytes = (stbi_uc *)image;
    for (row = 0; row < (h>>1); row++) {
        stbi_uc *row0 = bytes + row * bytes_per_row;
        stbi_uc *row1 = bytes + (h - row - 1) * bytes_per_row;
        size_t bytes_left = bytes_per_row;
        while (bytes_left) {
            size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp);
            memcpy(temp, row0, bytes_copy);
            memcpy(row0, row1, bytes_copy);
            memcpy(row1, temp, bytes_copy);
            row0 += bytes_copy;
            row1 += bytes_copy;
            bytes_left -= bytes_copy;
        }
    }
}

static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
    stbi__result_info ri;
    void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8);
    if (result == NULL) return NULL;
    if (ri.bits_per_channel != 8) {
        STBI_ASSERT(ri.bits_per_channel == 16);
        result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
        ri.bits_per_channel = 8;
    }
    // @TODO: move stbi__convert_format to here
    if (stbi_horizontally_flip_on_load) {
        int channels = req_comp ? req_comp : *comp;
        stbi_horizontal_flip(result, *x, *y, channels * sizeof(stbi_uc));
    }
    if (stbi__vertically_flip_on_load) {
        int channels = req_comp ? req_comp : *comp;
        stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc));
    }
    return (unsigned char *) result;
}

STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
{
    unsigned char *result;
    stbi__context s;
    stbi__start_file(&s,f);
    result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
    if (result) {
        // need to 'unget' all the characters in the IO buffer
        fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
    }
    return result;
}

STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp)
{
    FILE *f = stbi__fopen(filename, "rb");
    unsigned char *result;
    if (!f) return stbi__errpuc("can't fopen", "Unable to open file");
        result = stbi_load_from_file(f,x,y,comp,req_comp);
    fclose(f);
    return result;
}

STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
{
    stbi__context s;
    stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
    return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
}

void Gosu::load_image_file(Gosu::Bitmap& bitmap, const string& filename)
{
    Buffer buffer;
    load_file(buffer, filename);
    load_image_file(bitmap, buffer.front_reader());
}

void Gosu::load_image_file(Gosu::Bitmap& bitmap, Reader input)
{
    bool needs_color_key = is_bmp(input);
    stbi_io_callbacks callbacks;
    callbacks.read = read_callback;
    callbacks.skip = skip_callback;
    callbacks.eof = eof_callback;
    int x, y, n;
    stbi_uc* bytes = stbi_load_from_callbacks(&callbacks, &input, &x, &y, &n, STBI_rgb_alpha);
    if (bytes == nullptr) {
        throw runtime_error("Cannot load image: " + string(stbi_failure_reason()));
    }
    bitmap.resize(x, y);
    printf("Channels %d, Gosu Color size %d, unsigned char size %d, bytes array size %d",
         n, sizeof(Gosu::Color), sizeof(stbi_uc), sizeof(bytes));
    // Output: Channels 3 or 4, Gosu Color size 4, unsigned char size 1,       bytes array 8
    memcpy(bitmap.data(), bytes, x * y * sizeof(Gosu::Color));
    stbi_image_free(bytes);
    if (needs_color_key) apply_color_key(bitmap, Gosu::Color::FUCHSIA);
}```


// Output: Channels 3 or 4, Gosu Color size 4, unsigned char size 1, bytes array 8

That is what I got back from stb_image, but I'd prefer to get an 8bit array instead. Even so what actually matters is to get rid of that unexpected color change.
//我一直在尝试实现启用水平翻转的函数
静态void stbi_水平翻转(void*图像、int w、int h、int字节/u像素)
{
size\u t line\u bytes=(size\u t)w*每像素字节数;
stbi_uc temp[行字节];
stbi_uc*字节=(stbi_uc*)图像;

Debug()多亏了Igor的评论,我可以专注于眼前的问题,而且在我想出下面发布的代码后不久

自从我最终能够水平翻转图像以来,我一直在想,为什么我在web上或作为图像处理器代码的一部分找到的其他方法没有按预期工作。O_O?有时我复制并粘贴它们,只是更改一些变量的名称或类型以匹配stb_图像,但它们仍然无法编译或显示一个不错的结果

顺便说一句,我以前尝试过将位置减去正确的值,但没有效果,但这让我觉得其中一些可以用作很好的颜色混合效果

// Horizontal Flip by Kyonides Arkanthes shared under GPLv2 or v3
static void stbi_kyon_horizontal_flip(void *image, int w, int h, int bytes_per_pixel)
{
  size_t line_bytes = (size_t)w * bytes_per_pixel;
  stbi_uc temp[line_bytes];
  stbi_uc *bytes = (stbi_uc *)image;
  int lpos, rpos;
  for (int col = 0; col < h; col++) {
    stbi_uc *line = bytes + col * line_bytes;
    memcpy(&temp, line, line_bytes);
    for (int row = 0; row < w; row++) {
      lpos = row * bytes_per_pixel;
      rpos = line_bytes - row * bytes_per_pixel - 1;
      line[lpos] = temp[rpos - 3];
      line[lpos + 1] = temp[rpos - 2];
      line[lpos + 2] = temp[rpos - 1];
      line[lpos + 3] = temp[rpos];
    }
  }
  stbi_kyon_horizontally_flip_on_load = false;
}```
//Kyonides Arkanthes在GPLv2或v3下共享的水平翻转
静态void stbi_kyon_水平翻转(void*图像、int w、int h、int字节/u像素)
{
size\u t line\u bytes=(size\u t)w*每像素字节数;
stbi_uc temp[行字节];
stbi_uc*字节=(stbi_uc*)图像;
int LPO、RPO;
for(int col=0;col
您刚刚颠倒了RGBA的顺序,您尝试使用这个,我测试过,效果正常

            for (int row = 0; row < Qimg2.width(); row++) {
                lpos = row * bytes_per_pixel;
                rpos = line_bytes - row * bytes_per_pixel - 1;
                line[lpos] = temp[rpos - 2];
                line[lpos + 1] = temp[rpos - 1];
                line[lpos + 2] = temp[rpos - 3];
                line[lpos + 3] = temp[rpos];
            }
for(int row=0;row
您正在翻转单个字节,而不是整个像素。您需要交换每像素
字节组的相邻字节。例如,假设图像只有一个像素宽。翻转应该什么都不做。但是您的代码将每行从,例如,
{R,G,B}
更改为
{B,G,R}
,从而改变每个像素的颜色。顺便说一句,我认为这是故意对我的问题投反对票。我已经处理这个问题好几天了,尝试了几种变体。如果任何人都禁止犯错,那么像stackoverflow这样的网站现在甚至都不会上线。