|
Hi,
For an 8 bit grayscale image, between the header and pixel data, there will a color map of 256 colors. The color map will hold 256 shades of gray(ie R=G=B).
The actual pixel data will be a reference this color map. So fo creating 8 bit grayscale image do the following steps.
1. Open a file in binary mode.
2. Write Bitmap File header to file.
3. Write Bitmap Info header to file.
4. Write Colormap to file.
5. Write pixel data to file.
6. Close file.
Thanks
Akt_4_U
akt
|
|
|
|
|
Thanks very much, Akt!
But how do I write the Colormap? I wrote the following code, but I didn't get the grayscale anymore; instead, I got a more green color for the new image.
for(int c=0; c<256; c++)
{
fwrite((BYTE*)&bmpInfo.bmiColors[c], sizeof(RGBQUAD), 1, bmpFile);
}
Regards,
Ing LengIeng
Software Developer
|
|
|
|
|
Hope you have read the ColorMap completely from source bitmap. That is you have to allocate enough memory for reading the complete ColorMap(256 colors) for source image.
The following code will do this.
BYTE* pbyThumbImage // This is your source bitmap buffer.
const ULONG COLORMAP_START_OFFSET = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ); // Color map starts after Bitmap file header and Bitmap info header.
UINT uColorMapSize = 256 * sizeof( RGBQUAD );
pBmpInfoHdr = reinterpret_cast<lpbitmapinfo>( GlobalAllocPtr( GHND, sizeof( BITMAPINFOHEADER ) + uColorMapSize ));
memcpy( pBmpInfoHdr->bmiColors, ( pbyThumbImage + COLORMAP_START_OFFSET ), uColorMapSize ); // Now complete colormap information is within your pBmpInfoHdr->bmiColors.
Now you can write this colormap to destination file using fwrite with input buffer as pBmpInfoHdr->bmiColors and size to be written as uColorMapSize.
akt
|
|
|
|
|
But soon after I've finished reading the Colormap, I displayed the value of each RGB I can see that the color itself is of color more than the grayscale. I did so by comparing the RGB I get with the value in Microsoft Paint (mspaint.exe). That's why the result of the new image is rather a color one. How can I solve this?
Ing LengIeng
Software Developer
|
|
|
|
|
Which value did u take? R G and B from color map?
akt
|
|
|
|
|
Hi Akt,
Now I've solved my problem. I make the Colormap again by myself through the loop, and write it into the new bmp.
Thanks a lot!
Regards,
Ing LengIeng
Software Developer
|
|
|
|
|
Hi all,
I placed two edit boxes and two buttons in my dialog. I want to click the first button to clear the first edit box , and click the second button to clear the second edit box .
In the function of clicking the button, writing the following:
void CSerialPortTestDlg::OnBnClickedClearrec()
{
m_sEditRec.Empty();
UpdateData(0);
}
void CSerialPortTestDlg::OnBnClickedClearsend()
{
m_sEditSend.Empty();
UpdateData(0);
}
However, when I click one button , both edit boxes are cleared!!!
Could someone tell me why ?I write these codes in vc6.0 and it's no problem.
|
|
|
|
|
It looks like the DDX variable attached to second edit box is empty. So when you make an UpdateData(false), the editbox would get cleared. First save the value into the variable. In this case you might have used a CString. Assign some value for the string. If you want to keep the value that you entered in the edit box, first call UpdateData(true). Then try it wont get cleared.
Also don't save UpdateData(0), looks ugly. use "true-false".
He never answers anyone who replies to him. I've taken to calling him a retard, which is not fair to retards everywhere.-Christian Graus
|
|
|
|
|
Thanks a lot! I understand!
|
|
|
|
|
This is one of the reasons why UpdateData() should be avoided. Use this instead:
void CSerialPortTestDlg::OnBnClickedClearrec()
{
m_editRec.SetWindowText("");
}
void CSerialPortTestDlg::OnBnClickedClearsend()
{
m_editSend.SetWindowText("");
}
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
But this one won't clear the data. So won't that go out of sync, in case if he is using the CString variable after clicking these buttons?
He never answers anyone who replies to him. I've taken to calling him a retard, which is not fair to retards everywhere.-Christian Graus
|
|
|
|
|
VuNic wrote: So won't that go out of sync...
All the more reason to not use UpdateData() .
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
You don't recommend DDX as such?
He never answers anyone who replies to him. I've taken to calling him a retard, which is not fair to retards everywhere.-Christian Graus
|
|
|
|
|
Not using UpdateData() does not preclude the use of DDX.
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
Okay okay. thanks for the explanations.
He never answers anyone who replies to him. I've taken to calling him a retard, which is not fair to retards everywhere.-Christian Graus
|
|
|
|
|
Hi guys,
I am implementing a simple paint program and have trouble figure out how to draw an eclipse with arbitrary color and line width on memory device context.
I setup memory device context to save drawing screen before I blit it to a device context so that I can avoid flicker effect. Here is how I draw an ellipse with "default" pen and color:
// Assume that dc and outBitmap are initialized correctly by a caller
void DrawEllipse( CBitmap& outBitmap, CClientDC& dc, CPoint start, CPoint end, COLORREF color, int lineWidth )
{
CDC memdc;
memdc.CreateCompatibleDC( &dc );
outBitmap.CreateCompatibleBitmap( &dc, 500, 500 );
memdc.SelectObject( &outBitmap );
memdc.FillSolidRect( CRect( 0, 0, 500, 500 ), RGB( 255, 255, 255 ) );
memdc.Ellipse( start.x, start.y, end.x, end.y );
memdc.DeleteDC();
}
As a result, I got an ellipse with a default color and default width in my given bitmap instance.
How can I change a default color and default width?
I tried something like this and it magically works! But why !?
// Assume that dc and outBitmap are initialized correctly by a caller
void DrawEllipse( CBitmap& outBitmap, CClientDC& dc, CPoint start, CPoint end, COLORREF color, int lineWidth )
{
CDC memdc;
memdc.CreateCompatibleDC( &dc );
outBitmap.CreateCompatibleBitmap( &dc, 500, 500 );
memdc.SelectObject( &outBitmap );
memdc.FillSolidRect( CRect( 0, 0, 500, 500 ), RGB( 255, 255, 255 ) );
CPen pen( PS_SOLID, lineWidth, color );
memdc.SelectObject( &pen );
memdc.Ellipse( start.x, start.y, end.x, end.y );
memdc.DeleteDC();
}
Another question: CDC can have multiple GDI objects ?
THANKS GUYS!!
Un
|
|
|
|
|
There is nothing magical about it.
Any shape is drawn using a pen and a brush.
In the first code snippet you did not select a pen.
So it used the default pen.
A device context does have multiple objects like pen, brush, font, bitmap, region etc.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
Un Suthee wrote: Another question: CDC can have multiple GDI objects ?
A device context has a multiple GDI objects associated with it, but only one of each different obejct type. That is, there's one pen, one brush, one font etc. Each time you select a new one, it replaces the one that was previously selected. The return value from SelectObject is a pointer to the object that was previously selected, so you can select it back into the DC when you're finished with the object you selected. Here's an example using your code:
void DrawEllipse( CBitmap& outBitmap, CClientDC& dc, CPoint start, CPoint end, COLORREF color, int lineWidth )
{
CDC memdc;
memdc.CreateCompatibleDC( &dc );
outBitmap.CreateCompatibleBitmap( &dc, 500, 500 );
memdc.SelectObject( &outBitmap );
memdc.FillSolidRect( CRect( 0, 0, 500, 500 ), RGB( 255, 255, 255 ) );
CPen pen( PS_SOLID, lineWidth, color );
CPen* oldPen = memdc.SelectObject( &pen );
memdc.Ellipse( start.x, start.y, end.x, end.y );
memdc.SelectObject( oldPen );
memdc.DeleteDC();
}
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Un Suthee wrote: How to draw an eclipse
You should use different algorithms depending on the nature of the eclipse, is it solar eclipse or lunar one?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Groan...
Iain.
Codeproject MVP for C++, I can't believe it's for my lounge posts...
|
|
|
|
|
I'm kinda surprised. In your first code, you don't select any pen, then wonder why it uses the default one.
In the second one, you create and select a pen, then get surprised when it is used...
But I'd raise two more points. In your second code, you should keep track of the return value of the SelectObject call, and select the "old" pen back in.
Imagine the function that calls your DrawEllipse function. Imagine it has chosen to use a bright pink pen. Then it calls your code. And suddenly you're using a different colour. All because you didn't tidy up after yourself.
In this case, you'll probably get away with it, as the DC will be destroyed. But it's bad practise.
You've made the same error with the SelectObject (&outBmp) call. Where's the matching SelectObject (pOldBitmap)?
Lastly, why are you passing CClientDC as a parameter? If you made your function have the parent class CDC as a parameter, it will be more flexible in the future, at no cost to yourself. Feel free to use a CClientDC in the outer function, but DrawEllipse makes no use of the specialisation, so get rid of it.
Good luck,
Iain.
Codeproject MVP for C++, I can't believe it's for my lounge posts...
|
|
|
|
|
thanks all of you. Really.
Btw, I must be extremely tired on the day I wrote this post as I spelled ellipse as eclipse.
Un
|
|
|
|
|
how to use the interface of efs with vc6 ? where can I find some sample code?
modified on Tuesday, March 3, 2009 8:52 PM
|
|
|
|
|
I am currently developing an application using C++ and MFC. I am thinking about using the library called ChartDirectory. It is from a company called Advanced Software Engineering. This library offers a variety of classes for drawing charts. The company is in Hong King and I have never heard of them. They offer there documentation in both CHM format and in HTML format. I had problems reading the documentation in CHM format. It may have been that the file I down loaded was corrupt. I down loaded it a second time and it did not help. The HTML documentation, on the surface, looks good. However, I found a link that did not work. Therefore, I am not getting good vibes about their software.
I was wondering if anybody out there has used it, or even heard of it. If so, could you please tell me what you think about it.
Thanks
Bob
|
|
|
|
|
i have this formview with a ctreectrl in it and i need to change the tree's background to use a bitmap
i've found a couple of tutorials on how to do this, but they all involve deriving a class from ctreectrl and overriding either the OnPaint or the OnEraseBkgnd methods.
i can't do this since i'm not allowed to create a new class, so i'm stuck with changing stuff on the ctreectrl's parent window (formview)
i tried catching the notifications using ON_NOTIFY(WM_ERASEBKGND, IDC_TREE1, OnEraseBkgnd2) but it doesn't seem to work
i also tried changing the background in customdraw, but i could only get it to work during CDDS_PREPAINT and that produces some major painting issues
any suggestions? thanks
|
|
|
|
|