Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to create greyscale pixel value array

Status
Not open for further replies.

HuntsvilleRob

Programmer
Nov 3, 2010
26
US
Hello.
Thought I'd ask; having a hard time figuring this out on my own. I am using Borland C++ Builder 6 on a PC running Windows XP.

I have a black and white image; I can put it in any format, bmp, jpg, tif, whatever. The image has pixel dimensions 500 x 500. Each pixel is a greyscale value from 0 (black)to 2^16 (white). I want to write C++ code that will read the image file and create an array, call it DataArray[500][500] where DataArray[j] is the greyscale value for the pixel in the ith row, the jth column. How can I create such an array? This would allow me, for example, to create a graph of the greyscale values along any column (for all the rows) or along any row (for all the column values in that row). Any help would be greatly appreciated. Thanks.

-Rob
 
Have you tried Graphics::TBitmap? The members of the TCanvas of TBitmap include the Pixels property where you can access each pixel individually and the members of TBitmap include a ScanLine method where one can access either a horizontal or a vertical line of pixels via index.

If you don't mind me being nosy, HuntsvilleRob as in Huntsville, AL?

Steve.
 
Do you have any example code you could recommend?

Yes, Huntsville, AL!

Thanks. -Rob
 
...from memory:

Code:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	Graphics::TBitmap *bmpImage = new Graphics::TBitmap;
	AnsiString asImagePathNFilename = edtImagePathNFilename->Text;
	int iImageWidth, iImageHeight;

	bmpImage->LoadFromFile(asImagePathNFilename);
	iImageWidth = bmpImage->Width;
	iImageHeight = bmpImage->Height;
	for (iWhichXPixel = 0; iWhichXPixel < iImageWidth; iWhichXPixel++)
	{
		for (iWhichYPixel = 0; iWhichYPixel < iImageHeight; iWhichYPixel++)
		{
			bmpImage->Canvas->Pixels[iWhichXPixel][iWhichYPixel] = 0xFFFFFF - bmpImage->Canvas->Pixels[iWhichXPixel][iWhichYPixel];
		}
	}
	delete bmpImage;
}

You can explore TBitmap to squeeze out of it what you need. I have not used the ScanLine member before. Below is some example code from Builder help (by the way, TCanvas has a EASY TO USE StretchDraw method that will allow you to easily copy and double the size of an image):

Code:
/*
This example shows how to draw directly to a Bitmap.  It
loads a bitmap from a file and then copies it to another
bitmap twice it's size.  Then the two bitmaps are
displayed on the form canvas.
*/

#include <memory>       //for STL auto_ptr class

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  std::auto_ptr<Graphics::TBitmap> Bitmap(new Graphics::TBitmap);
  std::auto_ptr<Graphics::TBitmap> BigBitmap(new Graphics::TBitmap);
  TRGBTriple *ptr, *bigPtr;   // use a (byte *) for pf8bit color
  TPixelFormat pixForm, bigpixForm;
  try
  {
    Bitmap->LoadFromFile("../littlefac.bmp");
    pixForm = Bitmap->PixelFormat;
    bigpixForm  = BigBitmap->PixelFormat;
    Bitmap->PixelFormat = pf24bit;
    BigBitmap->PixelFormat = pf24bit;
    BigBitmap->Height = Bitmap->Height * 2;
    BigBitmap->Width = Bitmap->Width * 2;
    for (int y = 0; y < Bitmap->Height; y++)
    {
      ptr = reinterpret_cast<TRGBTriple *>(Bitmap->ScanLine[y]);
      for (int x = 0; x < Bitmap->Width; x++)
      {
        int bx = x * 2;
        int by = y * 2;
        bigPtr = reinterpret_cast<TRGBTriple *>(BigBitmap->ScanLine[by]);
        bigPtr[bx] = ptr[x];
        bigPtr[bx + 1] = ptr[x];
        bigPtr = reinterpret_cast<TRGBTriple *>(BigBitmap->ScanLine[by + 1]);
        bigPtr[bx] = ptr[x];
        bigPtr[bx + 1] = ptr[x];
      }
    }
    Canvas->Draw(0, 0, Bitmap.get());
    Canvas->Draw(200, 200, BigBitmap.get());
  }
  catch (...)
  {
    ShowMessage("Could not load or alter bitmap");
  }
}

I use the Pixels member of TCanvas, which is a member class of TBitmap, extensively. Pixels returns a TColor, which is four byte value (the upper-most byte is reserved by Builder, leaving the lower three bytes accessible as the color of the pixel). TBitmap supports practically all bitmap formats, including gray scale images and reduced color depth images.
Code:
	__property TColor Pixels[int X][int Y] = {read=GetPixel, write=SetPixel};

There are corresponding classes for JPEGs (jpeg.hpp) and PNGs (pngimage.hpp), which I have used in several programs.

Ultimately, if you can't get these to work, you will have to study the format of the image preambles so you can:
1.) Access the actual pixel data. The first 10's to 100's of bytes of image formats are preambles describing the image file. The classes handle all that for you.
2.) Decompress the image as necessary.

Hello from Madison, AL! Hope this helps!
Steve.
 
Hello, Steve! Thanks very much for the example code; this is just what I was looking for! I can now proceed.

Funny, looking for help in a world-wide forum leads me to the answer from a guy 10 minutes down 565 from me. So strange!

-Rob
 
With all the LabView crammed down my throat for engineering automation here in town, it is refreshing to know there is at least one other person here in town who uses Builder!

Let me know if you need anything else!

Steve.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top