mark_c wrote:I'm trying to study streaming video and I started building this simple example but it does not work.
That is because the code you have written has mistakes in it.
mark_c wrote:The code then first loads the image into memory and then displays it.
The way you are loading the image file into an AnsiString is very inefficient, there are much better ways to handle that. For instance, querying the file size first, then pre-sizing the AnsiString's memory, then reading the file bytes directly into the AnsiString's memory in one go. Or using System::Ioutils::TFile::ReadAllBytes(). Or using std::vector with a std::ifstream and std::istream_iterator. Or a number of other possible ways.
But, more importantly, you are type-casting the raw image data to a TStream* pointer, which is just plain wrong, not to mention that assignment is also causing a memory leak.
I would suggest getting rid of the AnsiString altogether (since you are not using it correctly anyway) and just use TMemoryStream by itself. It has a LoadFromFile() method.
You are also leaking the TJPEGImage (which incidentally also has a LoadFromFile() method).
mark_c wrote:after many tests I wrote this code but I do not know if it is efficient
Not only is it inefficient, it has quite a few bugs in it, most notably memory leaks, but also a couple of buffer overflow as well.
Try this instead:
- Code: Select all
void __fastcall TForm1::Button7Click(TObject *Sender)
{
TMemoryStream *picture = new TMemoryStream;
try
{
picture->LoadFromFile("img\\0001.jpg");
Label5->Caption = picture->Size;
TJPEGImage *myjpg = new TJPEGImage;
try
{
picture->Position = 0;
myjpg->LoadFromStream(picture);
Image1->Picture->Assign(myjpg);
}
__finally {
delete myjpg;
}
}
__finally {
delete picture;
}
}
Alternatively:
- Code: Select all
#include <memory>
void __fastcall TForm1::Button7Click(TObject *Sender)
{
std::auto_ptr<TMemoryStream> picture(new TMemoryStream); // or std::unique_ptr if using C++11
picture->LoadFromFile("img\\0001.jpg");
Label5->Caption = picture->Size;
std::auto_ptr<TJPEGImage> myjpg(new TJPEGImage); // or std::unique_ptr
picture->Position = 0;
myjpg->LoadFromStream(picture.get());
Image1->Picture->Assign(myjpg.get());
}
Note, you don't really need the TMemoryStream as TJPEGImage has its own LoadFromFile() method:
- Code: Select all
void __fastcall TForm1::Button7Click(TObject *Sender)
{
TJPEGImage *myjpg = new TJPEGImage;
try
{
myjpg->LoadFromFile("img\\0001.jpg");
Image1->Picture->Assign(myjpg);
}
__finally {
delete myjpg;
}
}
- Code: Select all
#include <memory>
void __fastcall TForm1::Button7Click(TObject *Sender)
{
std::auto_ptr<TJPEGImage> myjpg(new TJPEGImage); // or std::unique_ptr
myjpg->LoadFromFile("img\\0001.jpg");
Image1->Picture->Assign(myjpg.get());
}
For that matter, so does TPicture:
- Code: Select all
void __fastcall TForm1::Button7Click(TObject *Sender)
{
Image1->Picture->LoadFromFile("img\\0001.jpg");
}