Board index » cppbuilder » TImage subclass

TImage subclass


2003-07-01 10:10:16 PM
cppbuilder44
Hi,
I hope this is the right newsgroup to post my question.
We've developed a medical application, and we need to use a custom image
format (we call it "Zbi" format). Right now, we've developed a ZbiClass that
reads/writes bytes stream and we show them with StretchDIBits function, but
we'd like to have a "TZBIImage:TImage" class capable of reading/writing
images in Zbi format, and to show them in a form. I suppose I need to
subclass TImage, but I have no documentation on which methods I must
override, and so on... I would like to have some suggestions, links, ideas
;-)
Thanks in advance
Gianstefano Monni
 
 

Re:TImage subclass

Hi,
I hope this is the right newsgroup to post my question.
We've developed a medical application, and we need to use a custom image
format (we call it "Zbi" format). Right now, we've developed a ZbiClass that
reads/writes bytes stream and we show them with StretchDIBits function, but
we'd like to have a "TZBIImage:TImage" class capable of reading/writing
images in Zbi format, and to show them in a form. I suppose I need to
subclass TImage, but I have no documentation on which methods I must
override, and so on... I would like to have some suggestions, links, ideas
;-)
Thanks in advance
Gianstefano Monni
 

Re:TImage subclass

"Gianstefano Monni" < XXXX@XXXXX.COM >wrote in message news: XXXX@XXXXX.COM ...
Quote
Hi,
I hope this is the right newsgroup to post my question.
We've developed a medical application, and we need to use a custom image
format (we call it "Zbi" format). Right now, we've developed a ZbiClass that
reads/writes bytes stream and we show them with StretchDIBits function, but
we'd like to have a "TZBIImage:TImage" class capable of reading/writing
images in Zbi format, and to show them in a form. I suppose I need to
subclass TImage, but I have no documentation on which methods I must
override, and so on... I would like to have some suggestions, links, ideas
;-)
Thanks in advance
Gianstefano Monni


Derive a class from TGraphic and implement the pure virtual methods:
class TMyGraphic : public TGraphic
{
public:
__fastcall TMyGraphic();
void __fastcall Draw(TCanvas* C, const TRect& R );
bool __fastcall GetEmpty();
int __fastcall GetHeight();
int __fastcall GetWidth();
void __fastcall SetHeight(int Value);
void __fastcall SetWidth(int Value);
void __fastcall LoadFromStream(Classes::TStream* Stream);
void __fastcall SaveToStream(Classes::TStream* Stream);
void __fastcall LoadFromClipboardFormat(Word AFormat, UINT AData, HPALETTE APalette);
void __fastcall SaveToClipboardFormat(Word& AFormat, UINT& AData, HPALETTE& APalette);
void __fastcall SetPalette(HPALETTE APalette);
};
Then somewhere in your code do the following:
TMyGraphic* MyGraphic = new TMyGraphic();
Image1->Picture->Graphic = MyGraphic;
Todd
 

{smallsort}

Re:TImage subclass

The code you post gives the error
"Cannot assign a TMyGraphic to a TMyGraphic".
This code
TMyGraphic* gr = new TMyGraphic();
gr->Width=100;
gr->Height=100;
TRect *r = new TRect( 0,0,100,100);
gr->Draw(Image1->Canvas,*r);
paints the image correctly...
"Todd Brylski" < XXXX@XXXXX.COM >ha scritto nel messaggio
Quote
"Gianstefano Monni" < XXXX@XXXXX.COM >wrote in message
>Hi,
>I hope this is the right newsgroup to post my question.
>We've developed a medical application, and we need to use a custom image
>format (we call it "Zbi" format). Right now, we've developed a ZbiClass
that
>reads/writes bytes stream and we show them with StretchDIBits function,
but
>we'd like to have a "TZBIImage:TImage" class capable of reading/writing
>images in Zbi format, and to show them in a form. I suppose I need to
>subclass TImage, but I have no documentation on which methods I must
>override, and so on... I would like to have some suggestions, links,
ideas
>;-)
>Thanks in advance
>Gianstefano Monni
>
>

Derive a class from TGraphic and implement the pure virtual methods:

class TMyGraphic : public TGraphic
{
public:
__fastcall TMyGraphic();
void __fastcall Draw(TCanvas* C, const TRect& R );
bool __fastcall GetEmpty();
int __fastcall GetHeight();
int __fastcall GetWidth();
void __fastcall SetHeight(int Value);
void __fastcall SetWidth(int Value);
void __fastcall LoadFromStream(Classes::TStream* Stream);
void __fastcall SaveToStream(Classes::TStream* Stream);
void __fastcall LoadFromClipboardFormat(Word AFormat, UINT AData,
HPALETTE APalette);
void __fastcall SaveToClipboardFormat(Word& AFormat, UINT& AData,
HPALETTE& APalette);
void __fastcall SetPalette(HPALETTE APalette);
};

Then somewhere in your code do the following:

TMyGraphic* MyGraphic = new TMyGraphic();
Image1->Picture->Graphic = MyGraphic;


Todd




 

Re:TImage subclass

"Gianstefano Monni" < XXXX@XXXXX.COM >wrote in message
Quote
The code you post gives the error
"Cannot assign a TMyGraphic to a TMyGraphic".
That's due to not overloading the Assign() method. It's not a pure virtual
method so the compiler will let you get away with it. You'll need to add
one that looks something like this:
void __fastcall TMyGraphic::Assign(TPersistent* Source)
{
if (!Source || dynamic_cast <TMyGraphic*>(Source))
{
// *COPY* Source to "this" however your class requires it
}
else
TGrahpic::Assign(Source);
}
Quote
This code
...
paints the image correctly...
However, the image will disappear when the TImage gets invalidated. Fix the
Assign above and everything should work fine.
Also, to be able to tie into the LoadFromFile logic of TPicture add the
following code to your Zbi class' CPP file:
// Assuming your unit filename is ZBIImage use the following namespace
// If not, change as appropriate, remember to set the first character
// upercase and the rest lowercase
namespace Zbiimage
{
void __fastcall PACKAGE Register()
{
TPicture::RegisterFileFormat(__classid(TPicture),
"ZBI", "Whatever ZBI stands for", __classid(TZBIImage));
}
}
There are also a few more things you might end up having to do. I suggest
you use Google to search for previous posts where somebody derived from
TGraphic to create a new graphic class.
HTH
- Clayton
 

Re:TImage subclass

"Gianstefano Monni" < XXXX@XXXXX.COM >wrote in message
Quote
The code you post gives the error
"Cannot assign a TMyGraphic to a TMyGraphic".
You need to override Assign() in your custom TGraphic class so that you can
copy your image data from one instance to another.
Gambit
 

Re:TImage subclass

Gianstefano,
Quote
We've developed a medical application, and we need to use a custom
image format [...] we'd like to have a "TZBIImage:TImage" class capable
of reading/writing images in Zbi format, and to show them in a form.
If you need only to display the Zbi images at run time, then all you need to
do is convert from your format to a bitmap; specifically, you'd create a
TBitmap object of the correct dimensions, and then use the TBitmap::ScanLine
property to copy your raw array to the pixels of the bitmap--see the
ConstructBMP() function in this post tinyurl.com/g2g9. (You may also
need to use the SetDIBColorTable() Win32 function if the pixel values denote
color-table indices.) Instead of ScanLine, you could alternatively write to
a stream a properly initialized BITMAPFILEHEADER struct followed by your DIB
data (BITMAPINFO data + pixels), and then you'd use the
TBitmap::LoadFromStream() method to construct the bitmap--see
tinyurl.com/g2g4.
If you need to display your Zbi images at design time, then you'll need to
use the TPicture::RegisterFileFormat() member function. In this case, your
TZBIImage class should be a TGraphic descendant.
Good luck,
--
Damon (TeamB)
BCBCAQ - bcbcaq.bytamin-c.com
 

Re:TImage subclass

Hi,
thanks for your answer,I'm trying to sum up all the tips (I've posted the
question in vcl.componens.writing and graphics groups), and... I feel a bit
confused now ;-)
I mean, now I know I've to subclass TGraphic, and I must override some
methods of the class: in particular I must override
1. Assign
2. LoadFromStream: I must load data from a stream, unzip it (right now I'm
using zlib and it works as expected)
3. SaveToStream: I must save bitmap data and other medical data in a stream
filtering them with zlib
Could you tell me if I must use a private buffer, or there's a kind of
standard buffer to save this data ? I mean, TImage class use Pixels property
and ScanLine abstraction, there's something similar to use with TGraphic
class or I must implement it on my own ?
I have to
"Damon Chandler (TeamB)" < XXXX@XXXXX.COM >ha scritto nel messaggio
Quote
Gianstefano,
>We've developed a medical application, and we need to use a custom
>image format [...] we'd like to have a "TZBIImage:TImage" class capable
>of reading/writing images in Zbi format, and to show them in a form.

If you need only to display the Zbi images at run time, then all you need
to
do is convert from your format to a bitmap; specifically, you'd create a
TBitmap object of the correct dimensions, and then use the
TBitmap::ScanLine
property to copy your raw array to the pixels of the bitmap--see the
ConstructBMP() function in this post tinyurl.com/g2g9. (You may
also
need to use the SetDIBColorTable() Win32 function if the pixel values
denote
color-table indices.) Instead of ScanLine, you could alternatively write
to
a stream a properly initialized BITMAPFILEHEADER struct followed by your
DIB
data (BITMAPINFO data + pixels), and then you'd use the
TBitmap::LoadFromStream() method to construct the bitmap--see
tinyurl.com/g2g4.

If you need to display your Zbi images at design time, then you'll need to
use the TPicture::RegisterFileFormat() member function. In this case,
your
TZBIImage class should be a TGraphic descendant.

Good luck,
--
Damon (TeamB)
BCBCAQ - bcbcaq.bytamin-c.com
 

Re:TImage subclass

Hi,
thanks for your answer,I'm trying to sum up all the tips (I've posted the
question in vcl.componens.writing and graphics groups), and... I feel a bit
confused now ;-)
I mean, now I know I've to subclass TGraphic, and I must override some
methods of the class: in particular I must override
1. Assign
2. LoadFromStream: I must load data from a stream, unzip it (right now I'm
using zlib and it works as expected)
3. SaveToStream: I must save bitmap data and other medical data in a stream
filtering them with zlib
Could you tell me if I must use a private buffer, or there's a kind of
standard buffer to save this data ? I mean, TImage class use Pixels property
and ScanLine abstraction, there's something similar to use with TGraphic
class or I must implement it on my own ?
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >ha scritto nel messaggio
Quote

"Gianstefano Monni" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...
>The code you post gives the error
>"Cannot assign a TMyGraphic to a TMyGraphic".

You need to override Assign() in your custom TGraphic class so that you
can
copy your image data from one instance to another.


Gambit


 

Re:TImage subclass

"Gianstefano Monni" < XXXX@XXXXX.COM >wrote in message
Quote
now I know I've to subclass TGraphic, and I must
override some methods of the class: in particular I
must override
There are others, such as Draw(), GetEmpty(), GetHeight(), GetWidth(),
ReadData(), WriteData(), etc. Basically, if you look in Graphics.hpp, you
will see the declaration for the TGraphic class. You must implement all of
the abstract (pure virtual) methods, and you can optionally implement any of
the non-abstract virtual methods as well. There are quite a few of both.
Quote
Could you tell me if I must use a private buffer, or
there's a kind of standard buffer to save this data ?
You would use your own buffer. It is your own data, TGraphic has no concept
of what you are going to do with it. That is the whole point - TGraphic is
an abstract portal between your custom data and the rest of the VCL. It is
your own responsibility to implement the details of the data yourself
internally.
Quote
TImage class use Pixels property
No, it does not. It does all of its drawing using its inherited TCanvas
from TGraphicControl, calling its StretchDraw() method passing in whichever
TGraphic it is supposed to be displaying. TCanvas::StretchDraw() then calls
TGraphic::Draw(), which is one of the abstract methods you are required to
implement in your descendant class.
Quote
and ScanLine abstraction
ScanLine only applies to TBitmap specifically, not TGraphic generically.
TImage does not use ScanLine.
Gambit