Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++Bitmaparrays
Hello,
I have a question regrading about converting int into bmp. my objective is to convert the int into a greyscale bmp so i set Red blue green into the same value.
 
however because the value of 2d array is int array_ptr[1000][1536];(1536 col x 1000rows) which i have declare using double pointer,
This is how i declare my 2dArrays dynamically
 
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
 
                 unsigned int ptr = 0;
 
    int** array_ptr;
 
    array_ptr = new int * [1000];// Declare 1000 rows of arrays

    for(int i = 0; i < 1000; i++)
    {
    array_ptr[i] = new int[1536]; // 1536 column

    }
    for(int y = 0; y <1000; y++)
 
    {
            for(int x = 0; x <1536; x++)
 
            {
                    ptr++;
                    array_ptr[y][x] = (unsigned)(int) ptr;//pass the int 5 into the array
                    Application::DoEvents();
 
            }
    }
//How i use the Header File to convert the arrays of int into bitmap.
bool result = intarray2bmp::intarray2bmp( "foo.bmp", &(array_ptr[0][0]), 1000, 1536, 0, 9 );
             }
 
    };
 
took me weeks to learnt the pointers... and how silly was i to think i finally mastered memory allocation.. in the end now i still have problems with it.
 

 

i am only able to get the images at no more then row 9. i keep getting errors about
 
An unhandled exception of type;System.AccessViolationException&; occurred in ptr.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.;
 
below is the header file taken from a website.
 

i have try every possible way to increase the row but it's still stuck at row 9 .
 
if i try decreasing the col to 500 i can pull up the rows to 30 max.
 
Thank you. Below are the header files i used to convert the int into bmp.
appreicate any help if possible.
 
#ifndef INTARRAY2BMP_HPP
#define INTARRAY2BMP_HPP
 
#include <fstream>
#include <iostream>
#include <string>

namespace intarray2bmp
  {
 
  //-------------------------------------------------------------------------- 
  // This little helper is to write little-endian values to file.
  //
  struct lwrite
    {
    unsigned long value;
    unsigned      size;
    lwrite( unsigned long value, unsigned size ):
      value( value ), size( size )
      { }
    };
 
  //--------------------------------------------------------------------------
  inline std::ostream& operator << ( std::ostream& outs, const lwrite& v )
    {
    unsigned long value = v.value;
    for (unsigned cntr = 0; cntr < v.size; cntr++, value >>= 8)
      outs.put( static_cast <char> (value & 0xFF) );
    return outs;
    }
  //--------------------------------------------------------------------------
  // Take an integer array and convert it into a color image.
  //
  // This first version takes an array of array style of array:
  //   int* a[ 10 ]
  //
  // The second, overloaded version takes a flat C-style array:
  //   int a[ 10 ][ 10 ]
  //
  
					
  template <typename inttype="">
  bool intarray2bmp(
    const std::string& filename,
    IntType**          intarray,
    unsigned           rows,
    unsigned           columns,
    IntType            min_value,
    IntType            max_value
    ) {
    // This is the difference between each color based upon
    // the number of distinct values in the input array.
   // double granularity = 360.0 / ((double)( max_value - min_value ) + 1);

    // Open the output BMP file
    std::ofstream f( filename.c_str(),
                     std::ios::out | std::ios::trunc | std::ios::binary );
    if (!f) return false;
 
    // Some basic
    unsigned long headers_size    = 14  // sizeof( BITMAPFILEHEADER )
                                  + 40; // sizeof( BITMAPINFOHEADER )
    unsigned long padding_size    = (4 - ((columns * 3) % 4)) % 4;
    unsigned long pixel_data_size = rows * ((columns * 3) + padding_size);
 
    // Write the BITMAPFILEHEADER
    f.put( 'B' ).put( 'M' );                           // bfType
    f << lwrite( headers_size + pixel_data_size, 4 );  // bfSize
    f << lwrite( 0,                              2 );  // bfReserved1
    f << lwrite( 0,                              2 );  // bfReserved2
    f << lwrite( headers_size,                   4 );  // bfOffBits

    // Write the BITMAPINFOHEADER
    f << lwrite( 40,                             4 );  // biSize
    f << lwrite( columns,                        4 );  // biWidth
    f << lwrite( rows,                           4 );  // biHeight
    f << lwrite( 1,                              2 );  // biPlanes
    f << lwrite( 24,                             2 );  // biBitCount
    f << lwrite( 0,                              4 );  // biCompression=BI_RGB
    f << lwrite( pixel_data_size,                4 );  // biSizeImage
    f << lwrite( 0,                              4 );  // biXPelsPerMeter
    f << lwrite( 0,                              4 );  // biYPelsPerMeter
    f << lwrite( 0,                              4 );  // biClrUsed
    f << lwrite( 0,                              4 );  // biClrImportant

	 
    // Write the pixel data
    for (unsign%d row = rows; row; row--)           // bottom-to-top
      {
      for (unsigned col = 0; col < columns; col++)  // left-to-right
        {
        unsigned int red, green, blue;
                       #undef c
  
 
		red = intarray[row-1][col];
		green = intarray[row-1][col];
		blue = intarray[row-1][col];
 

        f.put( static_cast <char> (blue)  )
         .put( static_cast <char> (green) )
         .put( static_cast <char> (red)   );
        }
 
      if (padding_size) f << lwrite( 0, padding_size );
      }
 
    // All done!
    return f.good();
    }
 
  //--m-----------------------------------------------------------------------
  template <typename inttype="">
  bool intarray2bmp(
    const std::string& filename,
    IntType*           intarray,
    unsigned           rows,
    unsigned           columns,
    IntType            min_value,
    IntType            max_value
    ) {
    IntType** ia = new( std::nothrow ) IntType* [ rows ];
    for (unsigned row = 0; row < rows; row++)
      {
      ia[ row ] = intarray + (row * columns);
      }
    bool result = intarray2bmp(
                    filename, ia, rows, columns, min_value, max_value
                    );
    delete [] ia;
    return result;
    }
 
  } // namespace intarray2bmp

#endif
 
// end intarray2bmp.hpp</typename></char></char></char></typename></char></string></iostream></fstream>
http://www.cplusplus.com/forum/beginner/12848/[^]
Posted 22-Jul-12 22:29pm
NypStu334
Edited 23-Jul-12 5:41am
v3
Comments
nv3 at 23-Jul-12 5:19am
   
It seems that the code you pasted is not the code you are working with. For example is inttype spelled all lowercase in the template definition, but as IntType inside the intarray2bmp function. This won't even compile! Then please add also the source code of how you are calling the template function. Here is probably the error. The template function expects an array of pointers which point to single line buffers and not a 2D array!
NypStu at 23-Jul-12 12:24pm
   
hi nv3,thanks for your help, im currently working on this code. it is able to work. just that it dosent run over row 9.whenever i set row 10 and above i will get the errors. this is how i call the function after dynamically allocate int_array[1000][1536]; bool result = intarray2bmp::intarray2bmp( "foo.bmp", &(array_ptr[0][0]), 1000, 1536, 0, 9 );
nv3 at 23-Jul-12 16:44pm
   
This shouldn't even compile! The second argument &(array_ptr[0][0]) delivers an int*. But your function expects a int**. So give it as argument simply: array_ptr. That should fix the first problem. What I could not guess from your code is what you are finally trying to accomplish. Why do your first build a scattered array of ints and then convert it into a color bitmap, which only contains shades of gray? And the line: array_ptr[y][x] = (unsigned)(int) ptr;//pass the int 5 into the array even confuses me more. ptr is not a pointer, but an int. It has not the value 5, but is incremented on each cell. What are you trying to do here? My advice: Don't use code that you don't understand. By just guessing around you will not solve your problem fast. Try to understand C memory allocation and arrays and build your solution from there.
Stefan_Lang at 24-Jul-12 4:11am
   
You declared an int array by the name of int_array, but then passed the symbol array_ptr? What is the relation between the two, if any? It would be easier for everyone if you just posted the actual code in your initial posting. Please use the green colored link Improve question at the bottom of your question to do so. And yes, nv3 is correct, you passed a simple pointer rather than a pointer to a pointer to that function. Use &int_array instead. Note that if you declare a variable as a two-dimensional array, the variable name can be used as a simple pointer, so the following is always true: &(int_array[0][0]) == int_array
Stefan_Lang at 23-Jul-12 5:34am
   
On a sidenote: remove that template stuff. It doesn't make any sense, since the code in your class pretty much relies on the array element type to be a unsigned long It wouldn't work if you used any other type. [Edit]Ok, you said you pulled that code from a website, i. e. it isn't your code at all. In that case I suggest finding a different source, as this code is really not very good at all: as I mentioned the use of templates is wrong, I'm not even sure a default template argument of "" is supported by all compilers (it doesn't make sense in this context anyway), the naming is odd in places, and the code seems to make very specific assumptiona about the arguments being passed to the templates and functions - these are bound to cause problems if you don't meet these very specific assumptions in your own code.[/Edit]
NypStu at 23-Jul-12 12:20pm
   
Hi Stefan, thank you for your suggestion, i will continue to look out for a different source but in the mean time this is the closest to what i can get right now. the program only have problem once i set the rows to 11~ which inside a loop is 10. it is only able to run till maximum 9.
JackDingler at 23-Jul-12 16:56pm
   
What OS are you running this on? Are you sure that you have enough RAM to hold the image? Just in case, put in a test to make sure that your allocations did not fail.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

I'd have preferred to add this code to a comment, but it's just impractical for so many reasons.
 
Here's the code I had in the project I mentioned earlier. It does seem a bit funky now, some 4 1/2 years on - I think saveBMPfloat would be the easiest/quickest to modify. Just snip/replace the code that normalizes the values before they're saved.
 
I should also note that it expects a 1D array - i.e a 10x10 img would be
int myImg[10x10], rather than int myImg[10][10]. Same size, I come from a background using assembler (borland's tasm) & have always been used to handling the memory/indexing into arrays myself.
 

/*
 
  myBitmap.h
 
  Fri 22nd Feb 08
  enhzflep
 
*/
 
#ifndef myBitmap_H
 #define myBitmap_H
//#include "blenderOceanComplexT.h"
#include <windows.h>

typedef struct
{
        unsigned char iD[2];      // the magic number used to identify the BMP file: 0x42 0x4D (ASCII code points for B and M)
        unsigned int filesize;   // the size of the BMP file in bytes
        unsigned short reserved1;  // reserved; actual value depends on the application that creates the image
        unsigned short reserved2;  // reserved; actual value depends on the application that creates the image
        unsigned int dataOffset;  // the offset, i.e. starting address, of the byte where the bitmap data can be found.
} myBitmapHeader;
 
typedef struct
{
        long size;              //the size of this header (40 bytes)
        long bm_width;          //the bitmap width in pixels (signed integer).
        long bm_height;         //the bitmap height in pixels (signed integer).
        short  colPlanes;         //the number of color planes being used. Must be set to 1.
        short  bitsPerPixel;      //the number of bits per pixel, which is the color depth of the image. Typical values are 1, 4, 8, 16, 24 and 32.
        long compressionType;   //the compression method being used. See the next table for a list of possible values.
        long imageSize;         //the image size. This is the size of the raw bitmap data (see below), and should not be confused with the file size.
        long horRes;            //the horizontal resolution of the image. (pixel per meter, signed integer)
        long verRes;            //the vertical resolution of the image. (pixel per meter, signed integer)
        long paletteCols;       //the number of colors in the color palette, or 0 to default to 2n.
        long importantCols;     //the number of important colors used, or 0 when every color is important; generally ignore
} dibHeader;
 
//int saveBMPcomplex(char *filename, long xRes, long yRes, int normalize, blenderOceanComplexT *data);
//int saveBMP(char *filename, int xRes, int yRes, int normalize, blenderOceanComplexT *data);
//HBITMAP CreateBitmapFromPixelData( HDC hDC, UINT uWidth, UINT uHeight, UINT uBitsPerPixel, LPVOID pBits );
//unsigned char *LoadBitmapFile(char *filename, dibHeader *bitmapInfoHeader)

HBITMAP myLoadBitmapFromFile(char *fileName);
 
#endif
 

 

 

 
myBitmap.c
/*
 
   myBitmap.c
 
  Fri 22nd Feb 08
  enhzflep
 
   - simple functions used to get an array of floats into a windows bitmap image
   - could probably find one somewhere, but the net's down at the moment, and the
     bmp format is pretty simple
*/
 
#include "myBitmap.h"
#include "blenderOceanComplexT.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int saveBMPcomplexImag(char *filename, long xRes, long yRes, int normalize, blenderOceanComplexT *data);
 

//rowSize = 4 * ceil((n*width)/32);
long rowSize(int width, int bitsPixel)
{
     return 4 * ceil( (bitsPixel*width) / 32.0 );
}
 
// saves a greyscale bitmap file, from the imaginary part of an array of complex numbers
int saveBMPcomplexImag(char *filename, long xRes, long yRes, int normalize, blenderOceanComplexT *data)
{
    myBitmapHeader myHdr;
    dibHeader myDibHdr;
    FILE *output;
    int rowPadCount;
    long x, y;
    long datIndex;
    char pixel[3];   // holds b,g,r alue for each pixel
    char padPixel = 0;
 
    myHdr.iD[0] = 'B';
    myHdr.iD[1] = 'M';
    myHdr.reserved1 = 0;
    myHdr.reserved2 = 0;
    myHdr.dataOffset = 40 + 14; //sizeof(myDibHdr) + sizeof(myHdr);    //54
    myHdr.filesize = myHdr.dataOffset + (yRes*rowSize(xRes, 24));
 
    rowPadCount = rowSize(xRes, 24) - (xRes*3);
 
    myDibHdr.size = 40;
    myDibHdr.bm_width = xRes;
    myDibHdr.bm_height = yRes;
    myDibHdr.colPlanes = 1;
    myDibHdr.bitsPerPixel = 24;
    myDibHdr.compressionType = 0;
    myDibHdr.imageSize = yRes * rowSize(xRes, 24);
    myDibHdr.horRes = 2835; // pixels per meter  - works out to about 0.35 mm per pixel
    myDibHdr.verRes = 2835;
    myDibHdr.paletteCols = 0;
    myDibHdr.importantCols = 0;
 
    output = fopen(filename, "w");
    if (output == NULL)
       return 0;
 
    fwrite(&myHdr.iD, 1, 2, output);
    fwrite(&myHdr.filesize, 1, 4, output);
    fwrite(&myHdr.reserved1, 1, 2, output);
    fwrite(&myHdr.reserved2, 1, 2, output);
    fwrite(&myHdr.dataOffset, 1, 4, output);
 
    fwrite(&myDibHdr, 1, sizeof(myDibHdr), output);
    float max, min;
    if (normalize)
    {
        max = data[0].imag; min = data[0].imag;
        for (datIndex=0; datIndex<xRes*yRes; datIndex++)
        {
            if (min > data[datIndex].real)
               min = data[datIndex].real;
            if (max < data[datIndex].real)
               max = data[datIndex].real;
        }
    }
 
    else
    {
     min = -5.0;
     max = 5.0;
    }
 
    datIndex = 0;
    unsigned char blue, green, red, thisPixel;
    for (y=0; y<yRes; y++)
    {
        for(x=0; x<xRes; x++)
        {
           thisPixel = (unsigned char) 255.0*((data[datIndex].real - min)/(max-min));
           memset(pixel, thisPixel, 3);
           fwrite(pixel, 3, 1, output);
           datIndex++;
        }
        if (rowPadCount)
          fwrite(&padPixel, 1, rowPadCount, output);      // and write padded bytes to end of line
    }
    fclose(output);
    return 1;
}
 
// saves a greyscale bitmap file, from the imaginary part of an array of complex numbers
int saveBMPfloat(char *filename, int xRes, int yRes, int normalize, float *data)
{
    myBitmapHeader myHdr;
    dibHeader myDibHdr;
    FILE *output;
    int rowPadCount;
    long x, y;
    long datIndex;
    char pixel[3];   // holds b,g,r alue for each pixel
    char thisPixel;
    char padPixel = 0;
 
    myHdr.iD[0] = 'B';
    myHdr.iD[1] = 'M';
    myHdr.reserved1 = 0;
    myHdr.reserved2 = 0;
    myHdr.dataOffset = 40 + 14; //sizeof(myDibHdr) + sizeof(myHdr);    //54
    myHdr.filesize = myHdr.dataOffset + (yRes*rowSize(xRes, 24));
 
    rowPadCount = rowSize(xRes, 24) - (xRes*3);
 
    myDibHdr.size = 40;
    myDibHdr.bm_width = xRes;
    myDibHdr.bm_height = yRes;
    myDibHdr.colPlanes = 1;
    myDibHdr.bitsPerPixel = 24;
    myDibHdr.compressionType = 0;
    myDibHdr.imageSize = yRes * rowSize(xRes, 24);
    myDibHdr.horRes = 2835; // pixels per meter  - works out to about 0.35 mm per pixel
    myDibHdr.verRes = 2835;
    myDibHdr.paletteCols = 0;
    myDibHdr.importantCols = 0;
 
    output = fopen(filename, "w");
    if (output == NULL)
       return 0;
 
    fwrite(&myHdr.iD, 1, 2, output);
    fwrite(&myHdr.filesize, 1, 4, output);
    fwrite(&myHdr.reserved1, 1, 2, output);
    fwrite(&myHdr.reserved2, 1, 2, output);
    fwrite(&myHdr.dataOffset, 1, 4, output);
 
    fwrite(&myDibHdr, 1, sizeof(myDibHdr), output);
    float max, min;
    if (normalize)
    {
        max = data[0]; min = data[0];
        for (datIndex=0; datIndex<xRes*yRes; datIndex++)
        {
            if (min > data[datIndex])
               min = data[datIndex];
            if (max < data[datIndex])
               max = data[datIndex];
        }
    }
    else  // if !normalize
    {
     min = -5.0;
     max = 5.0;
    }
 
    datIndex = 0;
    unsigned char blue, green, red;
    for (y=0; y<yRes; y++)
    {
        for(x=0; x<xRes; x++)
        {
           thisPixel = (unsigned char) 255.0*((data[datIndex] - min)/(max-min));
           memset(pixel, thisPixel, 3);
           fwrite(pixel, 3, 1, output);
           datIndex++;
        }
        if (rowPadCount)
           fwrite(&padPixel, 1, rowPadCount, output);      // and write padded bytes to end of line
    }
    fclose(output);
    return 1;
}
 
HBITMAP CreateBitmapFromPixelData( HDC hDC, UINT uWidth, UINT uHeight, UINT uBitsPerPixel, LPVOID pBits )
{
      HBITMAP hBitmap = 0;
      if ( !uWidth || !uHeight || !uBitsPerPixel )
         return hBitmap;
      LONG lBmpSize = uWidth * uHeight * (uBitsPerPixel/8) ;       BITMAPINFO bmpInfo = { 0 };
      bmpInfo.bmiHeader.biBitCount = uBitsPerPixel;
      bmpInfo.bmiHeader.biHeight = uHeight;
      bmpInfo.bmiHeader.biWidth = uWidth;
      bmpInfo.bmiHeader.biPlanes = 1;
      bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
           // Pointer to access the pixels of bitmap       UINT * pPixels = 0;
      hBitmap = CreateDIBSection( hDC, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS, (void**)&pBits , NULL, 0);
 
      if ( !hBitmap )
          return hBitmap; // return if invalid bitmaps
      SetBitmapBits( hBitmap, lBmpSize,pBits);
      // Or Directly Write
      // memcpy(ptPixels, pBitmapBitmapBits, lBmpSize );
      //
      return hBitmap;
}
 
unsigned char *LoadBitmapFile(char *filename, dibHeader *bitmapInfoHeader)
{
    FILE *filePtr; //our file pointer
    myBitmapHeader bitmapFileHeader; //our bitmap file header
    unsigned char *bitmapImage;  //store image data
    int imageIdx=0;  //image index counter
    unsigned char tempRGB;  //our swap variable
    //open filename in read binary mode
    filePtr = fopen(filename,"rb");
    if (filePtr == NULL)
       return NULL;
    //read the bitmap file header - the compiler pads the 14 byte struct to 16
    // so we have to do it componenet by component :(
    fread(&bitmapFileHeader.iD, 2 ,1,filePtr);
    fread(&bitmapFileHeader.filesize, 4 ,1,filePtr);
    fread(&bitmapFileHeader.reserved1, 2 ,1,filePtr);
    fread(&bitmapFileHeader.reserved2, 2 ,1,filePtr);
    fread(&bitmapFileHeader.dataOffset, 4 ,1,filePtr);
 
    //verify that this is a bmp file by check bitmap id
    if ((bitmapFileHeader.iD[0] != 'B')||(bitmapFileHeader.iD[1] != 'M'))
    {
        fclose(filePtr);
        return NULL;
    }
    //read the bitmap info header
    fread(bitmapInfoHeader, sizeof(dibHeader),1,filePtr);
    //move file point to the begging of bitmap data
    fseek(filePtr, bitmapFileHeader.dataOffset, SEEK_SET);
    //allocate enough memory for the bitmap image data
    bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->imageSize);
    //verify memory allocation
    if (!bitmapImage)
    {
       free(bitmapImage);
       fclose(filePtr);
       return NULL;
    }
    //read in the bitmap image data
    fread(bitmapImage, 1, bitmapInfoHeader->imageSize, filePtr);
    //make sure bitmap image data was read
    if (bitmapImage == NULL)
    {
       fclose(filePtr);
       return NULL;
    }
    //swap the r and b values to get RGB (bitmap is BGR)
    for (imageIdx = 0; imageIdx < bitmapInfoHeader->imageSize; imageIdx+=3)
    {
        tempRGB = bitmapImage[imageIdx];
        bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
        bitmapImage[imageIdx + 2] = tempRGB;
    }
    //close file and return bitmap iamge data
    fclose(filePtr);
    return bitmapImage;
}
 
HBITMAP myLoadBitmapFromFile(char *fileName)
{
        dibHeader bmpInfo;
        unsigned char *pixelData;
        HBITMAP result;
        //now do what you want with it, later on i will show you how to display it in a normal window
        pixelData = LoadBitmapFile(fileName,&bmpInfo);
        result = CreateBitmapFromPixelData(NULL, bmpInfo.bm_width, bmpInfo.bm_height, bmpInfo.bitsPerPixel, pixelData);
        free(pixelData);
        return result;
}
  Permalink  
Comments
Stefan_Lang at 24-Jul-12 4:19am
   
Just by skimming over the code I'd say it's a lot better than what the OP uses! You may consider it funky, but I've found when dealing with pre-existing stuff (in this case the predefined bmp format) it is usally best to just be practical about it. ;-)
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 4

In my opinion you are making things more complicated than they have to be. Here is the code that allocates your 2-dimensional array:
 
    int** array_ptr;
    array_ptr = new int * [1000];     // 1000 row pointers
    for(int i = 0; i < 1000; i++)
        array_ptr[i] = new int[1536]; // 1000 row buffers, each 1536 ints long
 
Now, let's improve that step by step. First, why do you want to do 1537 allocations if you can do it in one? Yes, you can allocate a 2-dimensional array in just a single statement:
 
    int (*pArray)[1536] = new int[1000][1536];
 
This is not only more efficient, but also different in structure. In your code you have a vector of 1000 row pointers plus 1536 row buffers. In the new code you have a single memory block consisting of 1536000 cells of type int.
 
Notice the somewhat weird syntax for defining the pointer pArray. The parentheses are important. They make sure you are defining a pointer to an array of 1536 ints. Without the parentheses it would be an array of 1536 int-pointers.
 
You can (and should) later destroy that array by a single
 
    delete [] pArray;
 
The elements of your array can be addressed in just the same syntax as you did originally:
 
    pArray[y][x] = 5;
 
assigns the value of 5 to the cell in the column x and row y. Note that the x and y indices have to be specified in reverse order!
 
The next step is: Why do you want to allocate an int array if you are later going to reduce the array to a byte array. So use unsigned char instead of int:
 
    unsigned char (*pArray)[1536] = new unsigned char [1000][1536];
 
One last step is optional: As mentioned, the C syntax for working with 2-dimensional arrays is somewhat tricky. Therefore, many developers prefer to just use a 1-dimensional array and handle the coordinate mapping manually. For example like this:
 
    unsigned char *pArray = new unsigned char [1000*1536];
 
    // access to cell in row 5, column 7:
    pArray [5 * 1536 + 7] = 42;
 
That is eventually easier to comprehend than the somewhat tricky code above.
 
All that done, you will need to fix your intarray2bmp function, which is not the cleanest code anyhow. The functions in enhzflep's contribution will give you a much better foundation. So I would use these, instead.
  Permalink  
Comments
enhzflep at 24-Jul-12 8:49am
   
That's a really nice explanation of the practical differences between 1D and 2D arrays. For the reasons you mention that's exactly why I prefer 1D arrays. Also, compilers used to be considerably less effective at optimizing code. 1D arrays were almost always faster to use than 2D - since there were less addressing/bound-checking calcs to be done. Now a compiler may be smart enough to realize that you're iterating through all elements in a sequential manner. In this case the offset is calculated before the loop, with an index pointer simply incremented on each iteration of the loop. But again - succinct, articulate comparison of the two approaches. My +5!
nv3 at 24-Jul-12 8:57am
   
Thanks! And yes, most of the time you are better off handling the 2D addressing in your own code, in which you can draw the multiplication with the row length out of and before the inner loop. You did a nice job on your bitmap functions! I think NypStu is much better off using yours.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

I did something like this years ago when creating a series of images that could be used as a height-map for surface of an animated, windswept ocean. Lots of fun at the time in that one... Complex Numbers --> rgb images. WTF | :WTF:
 
Anyhow, a couple of questions that come to mind:
 
1. What's the resolution of the output - is it either of 1000x1536 or 1536x1000?
2. Do you need a bitmap file, or just an in-memory bitmap?
 
I'd be tempted to use GDI+ to save an HBITMAP to a file, combined with SetDibBits/CreateDIBitmap and a self-written putPixel function (one that would write to memory that was then blasted to a bitmap with SetDibBits)
 
If that proved too slow, I'd re-write the loops that set the pixels, such that they maintained a pointer into the memory that held the raw bits.
 

Pseudo:
1. Determine img dimensions - imgX, imgY
2. allocate enough memory for raw-image (no file header)
3. for curY = 0 to (imgY-1)
      for curX = 0 to (imgX-1)
         curVal = getSrcData(curX, curY);
         mySetPixel(curX, curY, val);
4. SetDibBits
5. Create GDI+ Image from HBITMAP used in step 4
6. call Image.save to put a copy on disk
 
CreateDIBitmap would be my sole choice if there's just 1 image. I'd also use SetDIBits if I had subsequent images.
 
Here's a few pertinent links:
 
GDI+ Image.Save[^]
SetDIBits[^]
CreateDIBitmap[^]
  Permalink  
Comments
NypStu at 23-Jul-12 11:57am
   
Hi enhzflep, Thank you for your help again, my objective is to get 1536 col x 1000 rows. i do need the bitmap file to do further analysing. my supervisor gave me this bitmap header and ask me to try and convert the int to a bitmap. i do also searched for other bitmap header files or any 3rd party software and this is probaly the closest to what i need to acomplish to do further enhancement. i do feel like i should learnt to write a bitmap files but he said given the time needed with my skills right now would takes another fews weeks which we can't afford to lose right now. so im still trying my best to see if i can edit anything out of this header file to get out the images in bitmap format.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Your Filters
Interested
Ignored
     
0 Guruprasad.K.Basavaraju 490
1 Sergey Alexandrovich Kryukov 316
2 Shai Vashdi 264
3 OriginalGriff 250
4 praveen_07 115
0 Sergey Alexandrovich Kryukov 9,185
1 OriginalGriff 5,315
2 Peter Leow 4,040
3 Maciej Los 3,535
4 Abhinav S 3,308


Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 24 Jul 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Use
Layout: fixed | fluid