如何使用stb_image将像素颜色数据写入 BMP 图像文件?
how can I write pixel color data to a bmp image file with stb_image?
我已经打开了 bmp 文件(一个通道灰度),并将每个像素颜色存储在新行中作为十六进制。 在对数据进行一些处理后(不是这个问题的重点),我需要从我的数据中导出一个 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 KByte)可能会被某些人视为潜在问题。另一种方法是改用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,但会对"错误报告"做出反应。
我默默地删除了
using namespace std;
:SO:为什么"使用命名空间 std"被认为是不好的做法?我添加了文件操作是否成功的检查。由于很多原因,文件操作总是失败的。对于文件写入,甚至
fclose()
也应进行测试。写入的数据可能会被缓存,直到文件关闭,并且仅将缓存的数据写入文件可能会失败(因为这可能会溢出可用卷空间)。OP使用幻数(图像宽度和大小),这被认为是不好的做法。它使代码维护变得不友好,并且可能更难让其他读者理解: SO:什么是幻数,为什么它是坏的?
- 为什么 BMP 图像上的 imwrite 会卡住/不返回?
- 将 BMP 图像转换为灰度
- 将 24 位".bmp"图像转换为黑白/单色图像的可能算法是什么?
- 如何确定 BMP 图像是否包含来自标题的 BGR 或 BGRA 像素
- 如何使用stb_image将像素颜色数据写入 BMP 图像文件?
- 在 C++/SDL2 中显示.bmp图像
- 在没有任何外部库的情况下,是否可以在c++/linux的窗口中显示bmp图像
- MFC-无法从资源输出BMP图像
- MPI BMP 图像比较更高效
- 使用 mfc 对话框显示.bmp图像时出错
- Openmp 渲染 bmp 图像
- 在visual Studio 2012上使用SDL加载.BMP图像时,它只显示一个帧
- 如何使用C++正确计算BMP图像中每像素的字节数
- 在窗口中显示BMP图像(C/C++)-图像消失
- 使用逐位运算符查找bmp图像的宽度和高度
- 如何将光标(鼠标指针对象)转换为bmp图像的自动序列
- 不知道如何保存 BMP 图像
- 在WINDOWS上写BMP图像格式错误
- 如何使用c++缩放bmp图像,仅使用iostream和stdio标头
- 以编程方式制作bmp图像