Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ create png/bitmap from array of numbers

So i found this link regarding my question, but it is for c#

Create a PNG from an array of bytes

I have a variable int array of numbers. i will call it "pix[ ]" for now it can be any size from 3 to 256, later possibly bigger.

What i want to do now, is to convert it into a pixel image. I am still a noobin c++ so pleas excuse me. I tried to download some libaries that make working with libpng easier, but they do not seem to be working (ubuntu, code::blocks) So i have questions in the following:

1) how do you create a new bitmap (which libaries, which command)?

2) how do i fill it with information from "pix[ ]" ?

3) how do i save it?

if it is a repost of a question i am happy about a link also ;)

Here is what i worked out so far, thanks for your help.

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);
}

i have not fully understood what it does. i can open the output image, but it is not a correct representation of the Array.

If i change things around, for example making a 2 dimensional array, then the image viewer tells me "expected an integer" and doesn't show me an image.

So far so good. As i have the array before the image i created a function aufrunden to round up to the next int number because i want to create a square image.

int aufrunden (double h)
{
int i =h;
if (h-i == 0)
  {
  return i;
  }
else
  {
  i = h+1;
  return i;
  }
}

This function is used in the creation of the image. If the image is bigger than the information the array provides like this (a is the length of th array)

double h;
h= sqrt(a/3.0);
int i = aufrunden(h);
FILE *imageFile;                           
int height=i,width=i;

It might happen now, that the array is a=24 long. aufrunden makes the image 3x3 so it has 27 values...meaning it is missing the values for 1 pixel. Or worse it is only a=23 long. also creating a 3x3 image.

What will fwrite(pix,1,18,imageFile); write in those pixels for information? It would be best if the remaing values are just 0.

*edit never mind, i will just add 0 to the end of the array until it is filling up the whole square...sorry

like image 666
busssard Avatar asked Mar 29 '16 15:03

busssard


Video Answer


2 Answers

Consider using a Netpbm format (pbm, pgm, or ppm).

These images are extremely simple text files that you can write without any special libraries. Then use some third-party software such as ImageMagick, GraphicsMagick, or pnmtopng to convert your image to PNG format. Here is a wiki article describing the Netpbm format.

Here's a simple PPM image:

P3 2 3 255
0 0 0       255 255 255
255 0 0     0 255 255
100 100 100 200 200 200

The first line contains "P3" (the "magic number identifying it as a text-PPM), 2 (width), 3 (height), 255 (maximum intensity). The second line contains the two RGB pixels for the top row. The third and fourth lines each contain the two RGB pixels for rows 2 and 3.

Use a larger number for maximum intensity (e.g. 1024) if you need a larger range of intensities, up to 65535.

Edited by Mark Setchell beyond this point - so I am the guilty party!

The image looks like this (when the six pixels are enlarged):

enter image description here

The ImageMagick command to convert, and enlarge, is like this:

convert image.ppm -scale 400x result.png

If ImageMagick is a bit heavyweight, or difficult to install you can more simply use the NetPBM tools (from here) like this (it's a single precompiled binary)

pnmtopng image.ppm > result.png
like image 120
Glenn Randers-Pehrson Avatar answered Oct 23 '22 01:10

Glenn Randers-Pehrson


If, as it seems, you have got Magick++ and are happy to use that, you can write your code in C/C++ like this:

////////////////////////////////////////////////////////////////////////////////
// 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"); 
}

enter image description here

like image 45
Mark Setchell Avatar answered Oct 23 '22 03:10

Mark Setchell