Board index » cppbuilder » 24 bit bitmaps

24 bit bitmaps

Hello Leonillo,

Leonillo <sale...@dis.uniroma1.it> schreef in berichtnieuws
393774D7.81D0A...@dis.uniroma1.it...

Quote
> Hi folks,
> I'm having some trouble working on a bitmap generated by a convertion
> from a file in a rgb format. When I set the pixel format to pf24bit and
> I try to write into the single pixels (using the pointer obtained with
> ScanLine), all I obtain is an access violation error. Can someone
> suggest me a way to avoid it?

Hmm, did you use a RGBTRIPLE pointer, like:

for( int y=0; y<Bmp->Height; ++y) {
  RGBTRIPLE *pLine = (RGBTRIPLE*)Bmp->ScanLine[y];
  for( int x=0; x<Bmp->Width; ++x) {
    pLine[x] = // do your stuff...
    ....
  }

Quote
}
> Thank you

Hope so...;-))

Quote
> Leonillo

--
Greetings from sunny Amsterdam

                Jan

email: bijs...@worldonline.nl
http://home.worldonline.nl/~bijster

 

Re:24 bit bitmaps


Having a similiar problem

My error is

Project Project1.exe raised exception class EAccessViolation with
message 'Access violation at address 004016FD.  Read of address
82C5F001'.  Process stopped.  Use Step or Run to continue.

Here is the project

//---------------------------------------------------------------------------

#pragma hdrstop
#include <condefs.h>
#include <vcl.h>
#include <stdio.h>
#include <fstream.h>
#pragma argsused
//---------------------------------------------------------------------------

struct testpixel
{
Byte Red;
Byte Green;
Byte Blue;

Quote
};

#include "Unit1.h"
//---------------------------------------------------------------------------

//#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{

FILE* outfile;

outfile = fopen("data.txt", "wb");

    Graphics::TBitmap* pBitmap=new Graphics::TBitmap;
    pBitmap->PixelFormat=pf24bit;
    pBitmap->LoadFromFile("test1.bmp");
    Graphics::TBitmap* ptempBitmap=new Graphics::TBitmap;
    ptempBitmap->PixelFormat=pf24bit;
    byte* linePtr,*pixelPtr;

/////////////////////////////////////////////////////////////
//
//  Method to Grab the pixels off of the bitmap
//
/////////////////////////////////////////////////////////////

    int numberPix = pBitmap->Height * pBitmap->Width;
    testpixel *pixel = new testpixel [numberPix];

    for (int y = 0; y < pBitmap->Height; y++)
    {
      linePtr = (byte *)pBitmap->ScanLine[y];

      for (int x = 0; x < pBitmap->Width; x++)
      {
      pixelPtr = linePtr+3*x;
      pixel[x].Red = pixelPtr[2];
      pixel[x].Green = pixelPtr[1];
      pixel[x].Blue = pixelPtr[0];

      fprintf(outfile, " %d R",pixel[x].Red);
      fprintf(outfile, " %d G",pixel[x].Green);
      fprintf(outfile, " %d B",pixel[x].Blue);
      fprintf(outfile, " - ");
      }

    }

fprintf(outfile, "Done");
fclose(outfile);
exit(0);

Quote
}

//---------------------------------------------------------------------------
Quote
J.A. Bijsterbosch wrote:
> Hello Leonillo,

> Leonillo <sale...@dis.uniroma1.it> schreef in berichtnieuws
> 393774D7.81D0A...@dis.uniroma1.it...
> > Hi folks,
> > I'm having some trouble working on a bitmap generated by a convertion
> > from a file in a rgb format. When I set the pixel format to pf24bit and
> > I try to write into the single pixels (using the pointer obtained with
> > ScanLine), all I obtain is an access violation error. Can someone
> > suggest me a way to avoid it?

> Hmm, did you use a RGBTRIPLE pointer, like:

> for( int y=0; y<Bmp->Height; ++y) {
>   RGBTRIPLE *pLine = (RGBTRIPLE*)Bmp->ScanLine[y];
>   for( int x=0; x<Bmp->Width; ++x) {
>     pLine[x] = // do your stuff...
>     ....
>   }
> }

> > Thank you

> Hope so...;-))

> > Leonillo

> --
> Greetings from sunny Amsterdam

>                 Jan

> email: bijs...@worldonline.nl
> http://home.worldonline.nl/~bijster

Re:24 bit bitmaps


The program works on bitmap files that I create in Paint, but doesn't work
on
files that I have translated from the JPG file format using the Internet
Explorer option set as wallpaper.  And since I'm using the loadFromFile()
maybe it isn't loading the correct width and height of the bitmap causing me

to enter into areas of memory that doesn't belong to the program.  Does this

seem plausible.

Bill

I've made the recommended changes, but still the same problem.

#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include <fstream.h>
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
        Tdata *Mydata = new Tdata;

struct testpixel
{
Byte Red;
Byte Green;
Byte Blue;

Quote
};

__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)
{
    FILE* outfile;
    outfile = fopen("data", "wb");

    Mydata->dataman(outfile);

    fclose(outfile);

Quote
}

Tdata::dataman(FILE* file)
{
    Graphics::TBitmap* pBitmap=new Graphics::TBitmap;
    pBitmap->PixelFormat=pf24bit;
    pBitmap->LoadFromFile("hello.bmp");

    TRGBTriple* linePtr;

/////////////////////////////////////////////////////////////
//
//  Method to Grab the pixels off of the bitmap in question
//
/////////////////////////////////////////////////////////////

    int numberPix = pBitmap->Height * pBitmap->Width;
    testpixel *pixel = new testpixel [numberPix];

    for (int y = 0; y < pBitmap->Height; ++y)
    {
        linePtr= (TRGBTriple*) pBitmap->ScanLine[y];

      for (int x = 0; x < pBitmap->Width; ++x)
      {

      pixel[x].Red = linePtr[x].rgbtRed;
      pixel[x].Green = linePtr[x].rgbtGreen;
      pixel[x].Blue = linePtr[x].rgbtBlue;

      fprintf(file, " * ");

      fprintf(file, " %d R",pixel[x].Red);
      fprintf(file, " %d G",pixel[x].Green);
      fprintf(file, " %d B",pixel[x].Blue);
      }

    }

       return 0;

Quote
}

Re:24 bit bitmaps


Quote
Bill wrote:
> Having a similiar problem

> My error is

> Project Project1.exe raised exception class EAccessViolation with
> message 'Access violation at address 004016FD.  Read of address
> 82C5F001'.  Process stopped.  Use Step or Run to continue.

> Here is the project

> __fastcall TForm1::TForm1(TComponent* Owner)
>     : TForm(Owner)
> {

> FILE* outfile;

> outfile = fopen("data.txt", "wb");

>     Graphics::TBitmap* pBitmap=new Graphics::TBitmap;
>     pBitmap->PixelFormat=pf24bit;
>     pBitmap->LoadFromFile("test1.bmp");
>     Graphics::TBitmap* ptempBitmap=new Graphics::TBitmap;
>     ptempBitmap->PixelFormat=pf24bit;
>     byte* linePtr,*pixelPtr;

> /////////////////////////////////////////////////////////////
> //
> //  Method to Grab the pixels off of the bitmap
> //
> /////////////////////////////////////////////////////////////

>     int numberPix = pBitmap->Height * pBitmap->Width;
>     testpixel *pixel = new testpixel [numberPix];

>     for (int y = 0; y < pBitmap->Height; y++)
>     {
>       linePtr = (byte *)pBitmap->ScanLine[y];

>       for (int x = 0; x < pBitmap->Width; x++)
>       {
>       pixelPtr = linePtr+3*x;
>       pixel[x].Red = pixelPtr[2];
>       pixel[x].Green = pixelPtr[1];
>       pixel[x].Blue = pixelPtr[0];

pixel[x]? You are sure that is what you want write?
pixel[x+pBitmap->Width*y] seems better, no?

Quote

>       fprintf(outfile, " %d R",pixel[x].Red);
>       fprintf(outfile, " %d G",pixel[x].Green);
>       fprintf(outfile, " %d B",pixel[x].Blue);
>       fprintf(outfile, " - ");
>       }

>     }

> fprintf(outfile, "Done");
> fclose(outfile);
> exit(0);
> }

I'm not see where is the acces violation, but why you not use TRGBTriple
structure:

TRGBTriple* linePtr;
...
linePtr= (TRGBTriple*) pBitmap->ScanLine[y];
...
red = linePtr[x].trgbRed; // I'm not sure of name of the field
...
It's work very well.

A last thing, where use you the  ptempBitmap ?

Re:24 bit bitmaps


Quote
Bill wrote:
> The program works on bitmap files that I create in Paint, but doesn't work
> on
> files that I have translated from the JPG file format using the Internet
> Explorer option set as wallpaper.  And since I'm using the loadFromFile()
> maybe it isn't loading the correct width and height of the bitmap causing me

> to enter into areas of memory that doesn't belong to the program.  Does this

> seem plausible.

> Bill

If you're not sure of the loading, just test the bitmap before using it.

ShowMessage(IntToStr(pBitmap->Width));
ShowMessage(IntToStr(pBitmap->Height));
switch(pBitmap->PixelFormat)
{
    case pf24bit:
            ShowMessage("pf24bit");
            break;
    case pf16bit:
            ShowMessage("pf16bit");
            break;
    case pf8bit:
            ShowMessage("pf8bit");
            break;
    default:
            ShowMessage("pf???bit");
            break;

Quote
}

And I see a other thing in your code : you set the pixelformat of the bitmap
before load it. However the loading function set the pixelformat at the
pixelformat of the bitmap file, you will do something special with this code ?

Re:24 bit bitmaps


Hello Bill,

Quote
> Having a similiar problem

> My error is

> Project Project1.exe raised exception class EAccessViolation with
> message 'Access violation at address 004016FD.  Read of address
> 82C5F001'.  Process stopped.  Use Step or Run to continue.

Hmm, an overrun of the array bounds in this case I suspect<g>
Let's go through your code step by step.

[ snip ]

Quote
> struct testpixel
> {
> Byte Red;
> Byte Green;
> Byte Blue;
> };

Well I would opt for using RGBTRIPLE as provided by the winapi, but if you
really want to use your own structure for this, the above is the first cause
for your problems. In bcb(version 4) internal data storage is 4 byte
aligned, what means that the above struct will not have the sizeof of 24
bits like you would expect. You can remedy this by using #pragma directives.
Rewrite the above struct as follows:

#pragma push(pack, 1)        // set to 1 byte alignment
typedef struct tag_testpixel {
  Byte Red, Green, Blue;

Quote
} testpixel, *ptestpixel;

#pragma push(pop)            // reset to previous alignment value

[ snip ]

Quote
>     byte* linePtr,*pixelPtr;

Although you could traverse the *LinePtr in steps of three for each RGB
color you would make it much easier on yourself to use a 24 bits struct like
you've just created<g> so do:
      ptestpixel LinePtr;

Quote
>     int numberPix = pBitmap->Height * pBitmap->Width;
>     testpixel *pixel = new testpixel [numberPix];

So far so good,  now do the following

     int w = pBitmap->Width;
     for (int y = 0; y < pBitmap->Height; y++) {
       linePtr = (ptestpixel)pBitmap->ScanLine[y];
       for (int x = 0; x < pBitmap->Width; x++) {
           // btw writing to file can be done more easy by LinePtr directly
           pixel[w*y+x]= LinePtr[x];

           fprintf(outfile, " %d R",pixel[w*y+x].Red);
           fprintf(outfile, " %d G",pixel[w*y+x].Green);
           fprintf(outfile, " %d B",pixel[w*y+x].Blue);
           fprintf(outfile, " - ");
       }
     }

Quote
> fprintf(outfile, "Done");
> fclose(outfile);

Don't forget to delete[] pixel; here to prevent memory leaks...
However, if you just want to write the pixel values directly to a file you
can ommit the whole testpixel *pixel all together and use the LinePtr in
fprintf instead.

Note I have not tested the above but, in principle, the code should work
now.

Hope this helped somewhat...;-))

Greetings from overcast Amsterdam

                Jan

email: bijs...@worldonline.nl
http://home.worldonline.nl/~bijster

Other Threads