?
Solved

Convert 24 bit to 8 bit grayscale

Posted on 2003-03-22
7
Medium Priority
?
374 Views
Last Modified: 2010-04-01
hi to all,
i want to convert 24 bit image to a 8 bit grayscale image
i write these codes but these doesnt work

void __fastcall TForm1::Button2Click(TObject *Sender)
{
   Graphics::TBitmap *bmp24 = new Graphics::TBitmap();
   Graphics::TBitmap *bmp8  = new Graphics::TBitmap();

   try
   {
     bmp24->LoadFromFile("asta.bmp");
     bmp8->Width=bmp24->Width;
     bmp8->Height=bmp24->Height;
     bmp8->PixelFormat=pf8bit;
     
     for (int y=0; y < bmp24->Height; y++)
     {
       Byte *ptr24 = new Byte[(bmp24->Width)*3];
       ptr24 = (Byte *)bmp24->ScanLine[y];
       Byte *ptr8 = new Byte[bmp24->Width];
       ptr8 = (Byte *)bmp8->ScanLine[y];
       for (int x=0; x< bmp24->Width; x++)
       {
         ptr8[x] = (Byte) ptr24[x*3];
       }
       delete [] ptr24;
       delete [] ptr8;
       delete ptr24;
//..
     }
   }
   catch (...)
   {
     ShowMessage("Could not load or alter bitmap");
   }
   bmp8->SaveToFile("asta8.bmp");

   delete bmp24;
   delete bmp8;
}

also delete commands give error. Why?
0
Comment
Question by:mece
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
7 Comments
 
LVL 22

Accepted Solution

by:
grg99 earned 80 total points
ID: 8186237
You cant just try to poke a 24-bit packed RGB value into an 8-bit grayscale location.

You have to take the individual RGB values and form a weighed average.   A raw first cut would be to just add the RGB values and divide by three.  That would give you a rough approximation of grayscale.  To do it right you should multiply each value by the right scaling factor.
One commonly used set of factors is:



R = 0.30

G = 0.59

B = 0.11

 
 Out = R * 0.3 + G * 0.59 + B * 0.11

--------------
Now in many computers flaoting-point multiplies are considerably slower than integer ones, so you'd probably recast this into 16-bit integer math, something like:

Out = (int8) ( ( (int16) R ) * (0.3 * 256 )) +
( (int16) G ) * (0.6 * 256 )) +
( (int16) R ) * (0.1 * 256 )) );

Of course you should first pre-compute those scaling factors and store them into int16's.




 

0
 

Author Comment

by:mece
ID: 8187702
i will try this code part

also why delete part does not work?
delete [] ptr24;
      delete [] ptr8;
      delete ptr24;
it gives error on run
0
 

Author Comment

by:mece
ID: 8187742
also i know that all red, green and blue values of my image are same. They are 24 bit images.
i want to convert them into 8 bit image.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 5

Expert Comment

by:Kocil
ID: 8188220
You don't need to use new and delete here.
Also, if your red,green,blue are the same,
You can just add them all and divide it by three
 ...
 for (int y=0; y < bmp24->Height; y++) {
    Byte *ptr24 = (Byte *)bmp24->ScanLine[y];
    Byte *ptr8 = (Byte *)bmp8->ScanLine[y];
    for (int x=0; x< bmp24->Width; x++)
    {
       *ptr8 = (ptr24[0]+ptr24[1]+ptr24[2]) / 3;
       ptr8 += 1; ptr24 += 3;
    }
 }
 ...
0
 
LVL 22

Expert Comment

by:grg99
ID: 8190022
"All the same" doesnt matter.  Even if the values of RGB are all scaledto go from 0 to 100%, the effective brightness doesnt get equal contributions from R, G, and B.

For example, the eye is very sensitive to green, so green contributes 60% of the apparent brightness.

The eye is very insensitive to blue, it only contributes 11% to brightness.  That is why you never see any bright, pure blue lights.

If you dont use the scaling factors, pictures will look very unusual, with grass looking black, and skies blindingly white.  You probably want better color balance than that!
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8190635
Good point grg.
0
 

Author Comment

by:mece
ID: 8191271
thanx grg
good point of view
i will try it
0

Featured Post

Enroll in August's Course of the Month

August's CompTIA IT Fundamentals course includes 19 hours of basic computer principle modules and prepares you for the certification exam. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

752 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