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