所以我找到了关于我的问题的这个链接,但它是针对c#
的Create a PNG from an array of bytes
我有一个变量int数组。 我会称之为“pix []” 现在它可以是3到256之间的任何大小,之后可能更大。
我现在要做的是将其转换为像素图像。 我仍然是一个noobin c ++,请原谅我。 我试图下载一些使libpng更容易使用的库,但它们似乎不起作用(ubuntu,code :: blocks) 所以我有以下问题:
1)如何创建新的位图(哪个libaries,哪个命令)?
2)如何用“pix []”中的信息填充它?
3)我如何保存?
如果是问题的重新发布我也对链接感到高兴;)
这是我到目前为止所做的工作,感谢您的帮助。
int main(){
FILE *imageFile;
int x,y,pixel,height=2,width=3;
imageFile=fopen("image.pgm","wb");
if(imageFile==NULL){
perror("ERROR: Cannot open output file");
exit(EXIT_FAILURE);
}
fprintf(imageFile,"P3\n"); // P3 filetype
fprintf(imageFile,"%d %d\n",width,height); // dimensions
fprintf(imageFile,"255\n"); // Max pixel
int pix[100] {200,200,200, 100,100,100, 0,0,0, 255,0,0, 0,255,0, 0,0,255};
fwrite(pix,1,18,imageFile);
fclose(imageFile);
}
我还没有完全明白它的作用。我可以打开输出图像,但它不是数组的正确表示。
如果我改变了一些东西,例如制作一个二维数组,那么图像查看器会告诉我“预期的整数”并且不会向我显示图像。
到目前为止一切顺利。
因为我在图像之前有数组我创建了一个函数aufrunden
来舍入到下一个int数,因为我想创建一个方形图像。
int aufrunden (double h)
{
int i =h;
if (h-i == 0)
{
return i;
}
else
{
i = h+1;
return i;
}
}
此功能用于创建图像。
如果图像大于数组提供的信息(a
是数组的长度)
double h;
h= sqrt(a/3.0);
int i = aufrunden(h);
FILE *imageFile;
int height=i,width=i;
现在可能会发生,数组长a=24
。 aufrunden
使图像为3x3,因此它有27个值...意味着它缺少1个像素的值。
或者更糟糕的是它只有a=23
长。还创建一个3x3图像。
fwrite(pix,1,18,imageFile);
在这些像素中写什么信息?如果剩余值仅为0,那将是最好的。
*编辑没关系,我只会在数组末尾添加0,直到填满整个广场...抱歉
答案 0 :(得分:6)
考虑使用Netpbm格式(pbm,pgm或ppm)。
这些图像是非常简单的文本文件,您可以在没有任何特殊库的情况下编写。然后使用某些第三方软件(如ImageMagick,GraphicsMagick或pnmtopng)将图像转换为PNG格式。这是一篇描述Netpbm format的维基文章。
这是一个简单的PPM图片:
P3 2 3 255
0 0 0 255 255 255
255 0 0 0 255 255
100 100 100 200 200 200
第一行包含" P3" ("幻数将其标识为文本-PPM),2(宽度),3(高度),255(最大强度)。 第二行包含顶行的两个RGB像素。 第三行和第四行各包含第2行和第3行的两个RGB像素。
如果您需要更大的强度范围(最多65535),请使用较大的数字表示最大强度(例如1024)。
Mark Setchell编辑超越这一点 - 所以我是一个有罪的派对!
图像看起来像这样(放大六个像素时):
要转换和放大的ImageMagick命令是这样的:
convert image.ppm -scale 400x result.png
如果ImageMagick有点重量级,或者难以安装,您可以更简单地使用NetPBM工具(来自here),这样(它是一个预编译的二进制文件)
pnmtopng image.ppm > result.png
答案 1 :(得分:4)
如果看起来像是Magick ++并且很乐意使用它,你可以用C / C ++编写代码:
////////////////////////////////////////////////////////////////////////////////
// sample.cpp
// Mark Setchell
//
// ImageMagick Magick++ sample code
//
// Compile with:
// g++ sample.cpp -o sample $(Magick++-config --cppflags --cxxflags --ldflags --libs)
////////////////////////////////////////////////////////////////////////////////
#include <Magick++.h>
#include <iostream>
using namespace std;
using namespace Magick;
int main(int argc,char **argv)
{
unsigned char pix[]={200,200,200, 100,100,100, 0,0,0, 255,0,0, 0,255,0, 0,0,255};
// Initialise ImageMagick library
InitializeMagick(*argv);
// Create Image object and read in from pixel data above
Image image;
image.read(2,3,"RGB",CharPixel,pix);
// Write the image to a file - change extension if you want a GIF or JPEG
image.write("result.png");
}
答案 2 :(得分:3)
你离我不远 - 尝试做得好!据我所知,你只有几个错误:
如果以二进制文字书写,您的P3
实际上需要P6
。
您使用的是int
类型的数据,而您需要将unsigned char
用于8位数据。
你的宽度和高度互换了。
您使用的PGM
扩展程序适用于便携式灰色地图,而您的数据是彩色的,因此您需要使用PPM
扩展程序,即for Portable Pix Map。
因此,工作代码如下所示:
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *imageFile;
int x,y,pixel,height=3,width=2;
imageFile=fopen("image.ppm","wb");
if(imageFile==NULL){
perror("ERROR: Cannot open output file");
exit(EXIT_FAILURE);
}
fprintf(imageFile,"P6\n"); // P6 filetype
fprintf(imageFile,"%d %d\n",width,height); // dimensions
fprintf(imageFile,"255\n"); // Max pixel
unsigned char pix[]={200,200,200, 100,100,100, 0,0,0, 255,0,0, 0,255,0, 0,0,255};
fwrite(pix,1,18,imageFile);
fclose(imageFile);
}
如果你再运行它,你可以将生成的图像转换为带有
的漂亮的大PNGconvert image.ppm -scale 400x result.png
如果您随后需要16位数据,则可以将255
更改为65535
,并存储在unsigned short
数组而不是unsigned char
中,当您来到fwrite()
,你需要写两倍的字节数。
答案 3 :(得分:1)
下面的代码将采用像素颜色的整数数组作为输入,并将其写入.bmp
位图文件。它仅需要<fstream>
库。输入参数path
可以是C:/path/to/your/image.bmp
,而data
的格式为data[x+y*width]=(red<<16)|(green<<8)|blue;
,其中red
,green
和blue
是0-255
范围内的整数,像素位置为(x,y)
。
#include <fstream>
void write_bitmap(const string path, const int width, const int height, const int* data) {
const int pad=(4-(3*width)%4)%4, filesize=54+(3*width+pad)*height; // horizontal line must be a multiple of 4 bytes long, header is 54 bytes
char header[54] = { 'B','M', 0,0,0,0, 0,0,0,0, 54,0,0,0, 40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,24,0 };
char padding[3] = { 0,0,0 };
for(int i=0; i<4; i++) {
header[ 2+i] = (unsigned char)((filesize>>(8*i))&255);
header[18+i] = (unsigned char)((width >>(8*i))&255);
header[22+i] = (unsigned char)((height >>(8*i))&255);
}
unsigned char* img = new unsigned char[3*width*height];
for(int i=0; i<width*height; i++) {
const int color = data[i];
img[3*i ] = (unsigned char)( color &255);
img[3*i+1] = (unsigned char)((color>> 8)&255);
img[3*i+2] = (unsigned char)((color>>16)&255);
}
ofstream file(path, ios::out|ios::binary);
file.write(header, 54);
for(int i=height-1; i>=0; i--) {
file.write((char*)(img+3*width*i), 3*width);
file.write(padding, pad);
}
file.close();
delete[] img;
}
该代码段的灵感来自Writing BMP image in pure c/c++ without other libraries