Solved

creating a Bitmap or DIB from an Pixel Array

Posted on 1997-11-19
7
439 Views
Last Modified: 2013-12-26
I've got an array of Bytes with i.e. 256x256 bytes that I'm receiving via TCP during program run, each byte representing one pixel with 256 grayscales. Now I want to put this array into a TBitmap or TDib instance, in order to be able to include it into a Window (TPictureWindow).
What must I do in order to get the pixel data into a defined structure of type TBitmap or TDib?
0
Comment
Question by:frane
7 Comments
 
LVL 3

Expert Comment

by:JPM
ID: 1299471
Have a look at SetDIBitsToDevice in the OWL API help
( put in a Paint Method )
0
 
LVL 3

Expert Comment

by:LucHoltkamp
ID: 1299472
Yes that should work nicely, however realcolor bitmaps (24 bits, no palette) crashes TDib. We couldn't get it to work and had to use DrawDib (MultiMedia API reference). This is intended for video, but is much more powerful than TDib when it comes to displaying bitmaps.
.luc.
0
 
LVL 3

Expert Comment

by:JPM
ID: 1299473
I have read my doc about image files :
"....24 bits...no color table....
 need a special hardware (sic!!!)
 time for displaying very high...."

I could recommend reading that book "
      Bitmapped Graphics programming in C++
       Mary Luse
           Addison Wesley

I got it a few years ago.
( ..I could have a look myself...)
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 3

Expert Comment

by:JPM
ID: 1299474
The  following code has been extracted from the book which title I gave.

pages 221/222 there are comments about 24 bits special code


//---------------------------
(C) Copyright Marv Luse
//--------------------------------------------------------//
//                                                        //
//   File:    IMGVIEWR.HPP                                //
//                                                        //
//   Desc:    Image viewer class                          //
//                                                        //
//--------------------------------------------------------//
#ifndef _IMGVIEWR_HPP_
#define _IMGVIEWR_HPP_

#include "color.hpp"               //    code  
#include "colormap.hpp"            //     not
#include "intenmap.hpp"            //     included
#include "dither.hpp"              //       in this "Comment"
#include "display.hpp"
#include "imgstore.hpp"

#ifndef _IMAGE_OPTIONS_
#define _IMAGE_OPTIONS_

//..................option values

#define  renderNONE    0x0000   // none specified
#define  renderMAP     0x0001   // palette mapping
#define  renderDITHER  0x0002   // dithering
#define  renderGRAY    0x0004   // force gray scale

#define  intensNONE    0x0000   // as-is
#define  intensICNT    0x0001   // increased contrast
#define  intensDCNT    0x0002   // decreased contrast
#define  intensIBRI    0x0004   // increased brightness
#define  intensDBRI    0x0008   // decreased brightness

#endif

//..................an image coordinate structure
struct ImCoord
{
   int xo;   // screen origin
   int yo;
   int x1;   // image upper left
   int y1;
   int x2;   // image lower right
   int y2;
};
//..................the image viewer class
class ImageViewer
{
   protected :
      // various stuff
      VgaDisplay    *disp;
      ImgStore      *image;
      Dither        *dit;
      // image and display palettes
      rgb           *imgpal;
      int            imgcnt;
      rgb           *devpal;
      int            devcnt;
      int           *clrmap;
      // display stuff
      int            scanwid;
      int            scanhgt;
      unsigned char *scanbuf;
      // options and flags
      int            rendopt;
      int            intnopt;
      int            status;
      int            panning;

   private:
      void mv_horz( ImCoord& ic, int dx );
      void mv_vert( ImCoord& ic, int dy );
      void go_home( ImCoord& ic );
      void go_end( ImCoord& ic );
      void alter_palette( rgb *pal, int npal );
      void erase( void );
      void draw( ImCoord& ic );

   public :
      ImageViewer( VgaDisplay *vga, ImgStore *map,
                   rgb *clrs, int nclrs,
                   int ropt, int iopt );
     ~ImageViewer( );
      int view( void );
};

#endif
//--------------------------------------------------------//
//                                                        //
//   File:    IMGVIEWR.CPP                                //
//                                                        //
//   Desc:    Image viewer class                          //
//                                                        //
//--------------------------------------------------------//
#include "stdlib.h"
#include "string.h"
#include "conio.h"

#include "imgviewr.hpp"

//..................keyboard interface stuff
enum ViewerCommands
{
   cmdError,
   cmdEscape,
   cmdEnter,
   cmdPanHalf,
   cmdPanFull,
   cmdHome,
   cmdEnd,
};
static int keys[] =
{
   0x1B, 0x0D,                  // esc, enter
   0x47, 0x4F,                  // home, end
   0x34, 0x4B, 0x36, 0x4D,      // left/right arrow
   0x38, 0x48, 0x32, 0x50,      // up/down arrow
   0x39, 0x49, 0x33, 0x51       // up/down page
};
static int keycmds[] =
{
   cmdEscape,  cmdEnter,
   cmdHome,    cmdEnd,
   cmdPanHalf, cmdPanFull, cmdPanHalf, cmdPanFull,
   cmdPanHalf, cmdPanFull, cmdPanHalf, cmdPanFull,
   cmdPanHalf, cmdPanFull, cmdPanHalf, cmdPanFull
};
static int keydxs[] =
{
    0,  0,
   -1,  1,
   -1, -2,  1,  2,
    0,  0,  0,  0,
    0,  0,  0,  0
};
static int keydys[] =
{
    0,  0,
   -1,  1,
    0,  0,  0,  0,
   -1, -2,  1,  2,
   -1, -2,  1,  2
};
static int nkeys = sizeof(keys) / sizeof(int);

static int getkey( int& dx, int& dy )
{
   while( 1 )
   {
      int k = getch();
      if( k == 0 ) k = getch();

      for( int i=0; i<nkeys; i++ )
         if( k == keys[i] )
         {
            dx = keydxs[i];
            dy = keydys[i];
            return keycmds[i];
         }
   }
}
//..................the viewer class
ImageViewer::ImageViewer( VgaDisplay *vga, ImgStore *map,
                          rgb *clrs, int nclrs,
                          int ropt, int iopt )
{
   disp    = vga;
   image   = map;
   dit     = 0;
   imgpal  = 0;
   imgcnt  = 0;
   devpal  = 0;
   devcnt  = 0;
   clrmap  = 0;
   rendopt = ropt;
   intnopt = iopt;
   status  = 0;
   panning = 0;

   // scan line buffer
   scanwid = disp->metric.ncolumns;
   scanhgt = disp->metric.nrows;
   scanbuf = new unsigned char [scanwid];
   if( scanbuf == 0 )
   {
      status = 1;
      return;
   }

   // allocate and initialize palettes
   // if image is palette based
   int i;
   if( nclrs > 0 )
   {
      imgpal = new rgb [nclrs];
      if( imgpal == 0 )
      {
         status = 1;
         return;
      }
      devpal = new rgb [nclrs];
      if( devpal == 0 )
      {
         status = 1;
         return;
      }
      clrmap = new int [nclrs];
      if( clrmap == 0 )
      {
         status = 1;
         return;
      }
      imgcnt = nclrs;
      for( i=0; i<imgcnt; i++ )
      {
         imgpal[i] = clrs[i];
         clrmap[i] = i;
      }

      // apply any requested palette modifications
      alter_palette( imgpal, imgcnt );

      // initialize device palette to image palette
      devcnt = imgcnt;
      for( i=0; i<imgcnt; i++ )
         devpal[i] = imgpal[i];
   }

   // nclrs == 0 implies a 24-bit color image,
   // which has no palette
   else
   {
      devcnt = ColorDiffusionSize(disp->metric.ncolors);
      devpal = new rgb [devcnt];
      if( devpal == 0 )
      {
         status = 1;
         return;
      }
      imgpal = new rgb [scanwid];
      if( imgpal == 0 )
      {
         status = 1;
         return;
      }
   }

   // if the image must be approximated...
   if( (disp->metric.ncolors < imgcnt) || (imgcnt == 0) )
   {
      if( (ropt & renderDITHER) || (imgcnt == 0) )
      {
         dit = new ColorDiffusionDither( scanwid,
                      imgpal, imgcnt,
                      ColorDiffusionPalette(),
                      ColorDiffusionSize(disp->metric.ncolors) );
         if( dit == 0 )
         {
            status = 1;
            return;
         }
         devcnt = ColorDiffusionSize(disp->metric.ncolors);
         for( i=0; i<devcnt; i++ )
            devpal[i] = ColorDiffusionPalette()[i];
      }
      else
      {
         devcnt = disp->metric.ncolors;
         reduce_palette( devpal, imgcnt, devcnt );
         color_map( imgpal, imgcnt, devpal, devcnt,
                    clrmap, 2 );
      }
   }

   // set the device palette
   disp->putpalette( devpal, devcnt );

   // panning necessary?
   if( (image->width() > scanwid) ||
       (image->height() > scanhgt) )
      panning = 1;
}

ImageViewer::~ImageViewer( )
{
   if( scanbuf ) delete [] scanbuf;
   if( imgpal )  delete [] imgpal;
   if( devpal )  delete [] devpal;
   if( clrmap )  delete [] clrmap;
   if( dit )     delete    dit;
}

void ImageViewer::alter_palette( rgb *pal, int npal )
{
   // apply any intensity mapping
   if( intnopt & intensICNT )
      contrast_alter( pal, npal, iMORE );
   if( intnopt & intensDCNT )
      contrast_alter( pal, npal, iLESS );
   if( intnopt & intensIBRI )
      brightness_alter( pal, npal, iMORE );
   if( intnopt & intensDBRI )
      brightness_alter( pal, npal, iLESS );

   // force grayscale?
   if( (rendopt & renderGRAY) || (disp->metric.ncolors == 2) )
   {
      for( int i=0; i<npal; i++ )
      {
         int g = pal[i].graylevel();
         pal[i] = rgb( g, g, g );
      }
   }
}

void ImageViewer::go_home( ImCoord& ic )
{
   if( image->width() > scanwid )
   {
      ic.xo = 0;
      ic.x1 = 0;
      ic.x2 = scanwid - 1;
   }
   else
   {
      ic.xo = (scanwid - image->width()) / 2;
      ic.x1 = 0;
      ic.x2 = image->width() - 1;
   }

   if( image->height() > scanhgt )
   {
      ic.yo = 0;
      ic.y1 = 0;
      ic.y2 = scanhgt - 1;
   }
   else
   {
      ic.yo = (scanhgt - image->height()) / 2;
      ic.y1 = 0;
      ic.y2 = image->height() - 1;
   }
}

void ImageViewer::go_end( ImCoord& ic )
{
   if( image->width() > scanwid )
   {
      ic.xo = 0;
      ic.x2 = image->width() - 1;
      ic.x1 = ic.x2 - scanwid + 1;
   }
   else
   {
      ic.xo = (scanwid - image->width()) / 2;
      ic.x1 = 0;
      ic.x2 = image->width() - 1;
   }

   if( image->height() > scanhgt )
   {
      ic.yo = 0;
      ic.y2 = image->height() - 1;
      ic.y1 = ic.y2 - scanhgt + 1;
   }
   else
   {
      ic.yo = (scanhgt - image->height()) / 2;
      ic.y1 = 0;
      ic.y2 = image->height() - 1;
   }
}

void ImageViewer::mv_horz( ImCoord& ic, int dx )
{
   int ds = scanwid - ic.xo - 1;
   if( (dx > 0) && (ic.x2 < image->width()-1) )
   {
      ic.x1 += dx;
      if( ic.x1 > ic.x2 )
          ic.x1 = ic.x2;
      ic.x2 = ic.x1 + ds;
      if( ic.x2 >= image->width() )
          ic.x2 = image->width() - 1;
   }
   else if( (dx < 0) && (ic.x1 > 0) )
   {
      ic.x1 += dx;
      if( ic.x1 < 0 )
          ic.x1 = 0;
      ic.x2 = ic.x1 + ds;
      if( ic.x2 >= image->width() )
          ic.x2 = image->width() - 1;
   }
}

void ImageViewer::mv_vert( ImCoord& ic, int dy )
{
   int ds = scanhgt - ic.yo - 1;
   if( (dy > 0) && (ic.y2 < image->height()-1) )
   {
      ic.y1 += dy;
      if( ic.y1 > ic.y2 )
          ic.y1 = ic.y2;
      ic.y2 = ic.y1 + ds;
      if( ic.y2 >= image->height() )
          ic.y2 = image->height() - 1;
   }
   else if( (dy < 0) && (ic.y1 > 0) )
   {
      ic.y1 += dy;
      if( ic.y1 < 0 )
          ic.y1 = 0;
      ic.y2 = ic.y1 + ds;
      if( ic.y2 >= image->height() )
          ic.y2 = image->height() - 1;
   }
}

void ImageViewer::erase( void )
{
   memset( scanbuf, 0, scanwid );
   for( int i=0; i<scanhgt; i++ )
      disp->putscanline( scanbuf, scanwid, 0, i );
}

void ImageViewer::draw( ImCoord& ic )
{
   int            n = ic.x2 - ic.x1 + 1;
   int            y = ic.yo;
   unsigned char *p = scanbuf;

   for( int i=ic.y1; i<=ic.y2; i++ )
   {
      if( dit )
      {
         if( imgcnt > 0 )
         {
            image->cpy( scanbuf, i, ic.x1, n );
            dit->dither( scanbuf, n );
         }
         else // 24-bit image
         {
            unsigned char *s;
            s = image->get( i ) + ic.x1*3;
            for( int j=0; j<n; j++ )
               imgpal[j] = rgb( *s++, *s++, *s++ );
            alter_palette( imgpal, n );
            ColorDiffusionDither *d =
            (ColorDiffusionDither *) dit;
            d->rgbdither( scanbuf, imgpal, n );
         }
      }
      else if( imgcnt > devcnt )
      {
         image->cpy( scanbuf, i, ic.x1, n );
         for( int j=0; j<n; j++ )
            scanbuf[j] = clrmap[scanbuf[j]];
      }
      else
      {
         p = image->get( i ) + ic.x1;
      }
      disp->putscanline( p, n, ic.xo, y++ );
   }
}

int ImageViewer::view( void )
{
   if( status != 0 ) return status;

   ImCoord ic;      // image/screen coords
   int     dx, dy;  // panning deltas

   erase();
   go_home( ic );
   draw( ic );

   while( status == 0 )
   {
      int k = getkey( dx, dy );

      if( (k==cmdEscape) || (k==cmdEnter) )
         status = k;

      else if( panning )
      {
         dx *= scanwid;  dx /= 2;
         dy *= scanhgt;  dy /= 2;

         // home
         if( (dx < 0) && (dy < 0) )
         {
            go_home( ic );
            erase();
            draw( ic );
         }

         // end
         else if( (dx > 0) && (dy > 0) )
         {
            go_end( ic );
            erase();
            draw( ic );
         }

         // pan left/right
         else if( ((dx > 0) && (ic.x2 < image->width()-1)) ||
                  ((dx < 0) && (ic.x1 > 0)) )
         {
            mv_horz( ic, dx );
            erase();
            draw( ic );
         }

         // pan left/right
         else if( ((dy > 0) && (ic.y2 < image->height()-1)) ||
                  ((dy < 0) && (ic.y1 > 0)) )
         {
            mv_vert( ic, dy );
            erase();
            draw( ic );
         }

         // anything else
         else
         {
            // printf( "\x07" );
         }
      }
   }

   return status;
}

0
 

Author Comment

by:frane
ID: 1299475
The answer doesn't match my question. I only want to know, how I can get the raw pixel data (an array of bytes, i.e. 256x256, each byte representing one grayscale pixel) into a TBitmap or TDib instance, because I don't know, how to tell the TBitmap or TDib instance, that this array represents the pixel data, with the method SetBitmapBits I didn't get it work. At the moment I don't need a paint routine. If I got the data into the TDib instance, the rest will work (hopefully).

0
 
LVL 3

Expert Comment

by:JPM
ID: 1299476
Sorry for the mistake, I didn't see the author of the comment wasn't the original !...ans obviously I was out!

Have you got a lok to the OWL API
        CreateDibSection
            BITMAPINFO
        CreateCompatibleBitmap
0
 
LVL 1

Accepted Solution

by:
tiago earned 100 total points
ID: 1299477
Just use the constructor:

    TBitmap(int width, int height, uint8 planes,
            uint8 count, void* bits=0);


Example: a 256x256 image with 24 bits true-color information on
     an array named pixels:

    TBitmap * bt = new TBitmap (256,256,1,24,(void *)pixels);

    Don't forget that the scanlines must be word aligned;
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This article covers the basics of the Sass, which is a CSS extension language. You will learn about variables, mixins, and nesting.
Shoutout to Emily Plummer (http://www.experts-exchange.com/members/eplummer26.html) for giving me this article! She did most of it, I just finished it up and posted it for her :)    Introduction In a previous article (http://www.experts-exchang…
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now