![](/img/trans.png)
[英]Loading PNG with stb_image for OpenGL texture gives wrong colors
[英]Loading image with stb_image library as float outputs wrong values
當我使用STB_Image將圖像加載為浮點數時,值似乎已關閉。 我創建了一個圖像來測試它 . (這里使用的 RGB 代碼是 [127, 255, 32])
當我使用stbi_load()
將此圖像加載為unsigned char
我得到了正確的值。 但是當我使用stbi_loadf()
它加載為float
我得到了錯誤的值,這對我來說沒有意義。
這是我用於測試的代碼:
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <sstream>
#include <iomanip>
#include <iostream>
#include <string>
struct ColorF {
float r;
float g;
float b;
float a;
std::string toString() {
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << "[" << this->r << ", " << this->g << ", " << this->b << ", " << this->a << "]";
return stream.str();
}
};
struct ColorUC {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
std::string toString() {
std::stringstream stream;
stream << "[" << (float) this->r / 255.0f << ", " << (float) this->g / 255.0f << ", " << (float) this->b / 255.0f << ", " << (float) this->a / 255.0f << "]";
return stream.str();
}
};
int main() {
int width, height, channels;
float* image = stbi_loadf("test.png", &width, &height, &channels, STBI_rgb_alpha);
// print content of first pixel of the image
std::cout << ((ColorF*) image)->toString() << std::endl;
unsigned char* jpeg = stbi_load("test.png", &width, &height, &channels, STBI_rgb_alpha);
// print content of first pixel of the image
std::cout << ((ColorUC*) jpeg)->toString() << std::endl;
stbi_image_free(image);
stbi_image_free(jpeg);
return 0;
}
我得到的測試輸出是這樣的:
[0.22, 1.00, 0.01, 1.00]
[0.50, 1.00, 0.13, 1.00]
從理論上講,這應該打印出相同的值,底部的值是正確的值,在兩行上,但由於某種原因它沒有。
現在我當然可以使用 unsigned char 值並為自己編寫一個函數,將所有內容轉換為正確的浮點值,但我覺得應該有一種方法可以僅使用 STB_Image 本身來做到這一點。
從stb_image.h
標題注釋:
// If you load LDR images through this interface, those images will
// be promoted to floating point values, run through the inverse of
// constants corresponding to the above:
//
// stbi_ldr_to_hdr_scale(1.0f);
// stbi_ldr_to_hdr_gamma(2.2f);
這意味着stbi_loadf()
函數使用內置伽馬校正來返回其浮點值。
伽馬校正公式如下所示:
Vout = (Vin / 255)^γ; Where γ = 2.2
當你把[127, 255, 32]
通過伽馬校正公式時,你會得到你看到的結果:
R: 0.22 = (127 / 255)^2.2
G: 1.00 = (255 / 255)^2.2
B: 0.01 = ( 32 / 255)^2.2
您可以使用stbi_ldr_to_hdr_gamma(1.0f)
設置 stb_image 伽馬系數作為快速修復。
但是,stb_image 專門定義了stbi_loadf()
以支持非線性編碼圖像(HDR 或伽馬校正)。 如果要使用該功能加載實際的 HDR 圖像,將 gamma 設置為1.0
會對繪制圖像的准確性產生負面影響; 因此,如果您確實需要使用伽馬校正加載圖像,最好只使用stbi_loadf()
。
現在我當然可以使用 unsigned char 值並為自己編寫一個函數,將每個值轉換為正確的浮點值,但我覺得應該有一種方法可以僅使用 STB_Image 本身來做到這一點。
使用Vout = (float)Vin / 255f
手動將 8 位圖像數據轉換為浮點數明顯告訴代碼的讀者,圖像數據沒有經過伽馬校正。 將stbi_loadf()
與stbi_ldr_to_hdr_gamma(1.0f)
可能會掩蓋這一重要細節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.