- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经打开了 bmp 文件(一个 channel 灰度)并将每个像素颜色存储在一个新行中作为十六进制。在对数据进行一些处理后(不是这个问题的重点),我需要从我的数据中导出一个 bmp 图像。如何加载文本文件(数据)并使用 stb_image_write
?
像素到图像:
#include <cstdio>
#include <cstdlib>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
using namespace std;
int main() {
FILE* datafile ;
datafile = fopen("pixeldata.x" , "w");
unsigned char* pixeldata ;//???
char Image2[14] = "image_out.bmp";
stbi_write_bmp(Image2, 512, 512, 1, pixeldata);
图像到像素:
#include <cstdio>
#include <cstdlib>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
using namespace std;
const size_t total_pixel = 512*512;
int main() {
FILE* datafile ;
datafile = fopen("pixeldata.x" , "w");
char Image[10] = "image.bmp";
int witdth;
int height;
int channels;
unsigned char *pixeldata = stbi_load( (Image) , &witdth, &height, &channels, 1);
if(pixeldata != NULL){
for(int i=0; i<total_pixel; i++)
{
fprintf(datafile,"%x%s", pixeldata[i],"\n");
}
}
}
最佳答案
这个问题有很多弱点——太多了,无法在评论中解决...
这个问题被标记为 C++。为什么容易出错fprintf()
?为什么不std::fstream
?它具有类似的功能(如果不是更多的话)但增加了类型安全(printf()
系列无法提供)。
fprintf()
的对应部分是 fscanf()
.格式化程序相似,但存储类型必须在格式化程序中配置,比在 fprintf()
中更仔细。 .
如果第一个代码示例是尝试从 datafile.x
中读取像素... 为什么 datafile = fopen("pixeldata.x" , "w");
?使用 fopen()
打开文件阅读,应该是"r"
.
char Image2[14] = "image_out.bmp";
是正确的(如果我算对了的话)但维护不友好。让编译器为您完成工作:
char Image2[] = "image_out.bmp";
要为(在 OP 的情况下)固定大小为 512 × 512 字节的像素数据提供存储,最简单的方法是:
unsigned char pixeldata[512 * 512];
在局部变量中存储该大小的数组(512 × 512 = 262144 字节 = 256 KB)可能被某些人视为潜在问题。另一种方法是使用 std::vector<unsigned char> pixeldata;
反而。 (std::vector
在堆内存中动态分配存储,其中局部变量通常位于一种堆栈内存中,而堆栈内存通常大小有限。)
关于 std::vector<unsigned char> pixeldata;
,我看到两个选项:
预分配定义:
std::vector<unsigned char> pixeldata(512 * 512);
这样就可以像上面的数组一样使用了。
没有预分配的定义:
std::vector<unsigned char> pixeldata;
这将允许将每个读取像素添加到 std::vector::push_back()
的末尾.
可能是值得预先保留最终大小,因为它从一开始就知道:
std::vector<unsigned char> pixeldata;
pixeldata.reserve(512 * 512); // size reserved but not yet used
所以,这就是它最终的样子:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
int main()
{
const int w = 512, h = 512;
// read data
FILE *datafile = fopen("pixeldata.x" , "r");
if (!datafile) { // success of file open should be tested ALWAYS
std::cerr << "Cannot open 'pixeldata.x'!\n";
return -1; // ERROR! (bail out)
}
typedef unsigned char uchar; // for convenience
std::vector<uchar> pixeldata(w * h);
char Image2[] = "image_out.bmp";
for (int i = 0, n = w * h; i < n; ++i) {
if (fscanf(datafile, "%hhx", &pixeldata[i]) < 1) {
std::cerr << "Failed to read value " << i << of 'pixeldata.x'!\n";
return -1; // ERROR! (bail out)
}
}
fclose(datafile);
// write BMP image
stbi_write_bmp(Image2, w, h, 1, pixeldata.data());
// Actually, success of this should be tested as well.
// done
return 0;
}
一些补充说明:
请对这段代码持保留态度。我没有编译或测试它。 (我将此作为任务留给 OP,但将对“错误报告”使用react。)
我悄悄删除了using namespace std;
: SO: Why is “using namespace std” considered bad practice?
我添加了文件操作是否成功的检查。由于很多原因,文件操作总是很容易失败。对于文件写入,即使是 fclose()
应该进行测试。写入的数据可能会被缓存,直到文件关闭,并且仅将缓存的数据写入文件可能会失败(因为这可能会溢出可用的卷空间)。
OP 使用魔数(Magic Number)(图像宽度和大小),这被认为是不好的做法。它使代码维护不友好,其他读者可能更难理解:SO: What is a magic number, and why is it bad?
关于c++ - 如何使用 stb_image 将像素颜色数据写入 bmp 图像文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55759672/
我一直在用 C++ 开发一个新项目,使用 GLFW 作为 OpenGL 包装器,并使用 stb_image.h 工具加载图像。 我使用以下代码片段加载图像: this->width = width;
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我正在使用 stb_image.c 将数据字节加载到 opengl。但是,当我尝试使用 alpha channel 加载 png 文件时,我遇到了一个问题 现在白色区域应该是透明的,虽然它只清除了一小
我创建并加载了这张图片: int x, y, comps; unsigned char* data = stbi_load(".//textures//heightMapTexture.png", &
我想将这张图片加载到二维纹理中,然后将其绘制到屏幕上。主要问题是将图片加载到纹理变量中。以下代码输出正确的宽度和高度以及 rgba,但我如何将数据放入 3d 纹理中。 #include #inclu
stb_image 似乎支持 idct 和 ycbcr->rgb 转换操作的插件 SIMD 实现,这在加载 jpeg 文件时占用了大部分时间。查看 STBI_SIMD 背后的代码,很明显这段代码实际上
我尝试加载的图像在呈现时旋转了 90 度。我使用的是“加载时垂直翻转图像”,但渲染纹理时,图像会旋转 90 度。 我尝试更改索引和 tex 坐标,但没有用。 //Mesh struct Mesh me
我已经打开了 bmp 文件(一个 channel 灰度)并将每个像素颜色存储在一个新行中作为十六进制。在对数据进行一些处理后(不是这个问题的重点),我需要从我的数据中导出一个 bmp 图像。如何加载文
我正在研究 OpenGL 驱动的 2d 引擎。 我正在使用 stb_image 加载图像数据,以便创建 OpenGL 纹理。我知道 OpenGL 的 UV 原点是左下角,我还打算在该空间中为我的屏幕空
我想使用 stb_image 库,作者已经把它放到了一个非常大的头文件中。要使用该库,文档告诉我将这两行添加到我的代码中。 #define STB_IMAGE_IMPLEMENTATION #incl
我已经下载了 stb_image.h ( https://github.com/nothings/stb ) 并包含在我想使用它的 .cpp 文件中。 然后我使用函数加载图像 image_data =
我正在使用 stb_image 加载一个 32 位 PNG 文件 (RGBA),并使用它创建一个 OpenGL 纹理。 它适用于 24 位 PNG 文件(没有 alpha channel ),但是当我
我是一名优秀的程序员,十分优秀!