Author |
Topic |
|
drmoorejr
USA
7 Posts |
Posted - Oct 26 2023 : 16:01:42
|
hi,
I would like to Serialize the TIEFTImage object into a byte array (TMemoryStream), What all do I need to consider when doing this?
Thanks,
David |
|
xequte
38611 Posts |
Posted - Oct 27 2023 : 02:07:55
|
Hi David
There's really not a good way to do that, unfortunately. The class could do with a method to stream the data. We'll consider that for a later release.
Nigel Xequte Software www.imageen.com
|
|
|
drmoorejr
USA
7 Posts |
Posted - Oct 27 2023 : 09:02:33
|
I think I figured it out. I will keep you posted, but this could be useful when sharing the FTImage data between apps. |
|
|
drmoorejr
USA
7 Posts |
Posted - Oct 27 2023 : 10:20:54
|
I created a button procedure that write the TIEFTImage data to a file:
procedure TForm1.btnExportFFTImageClick(Sender: TObject);
var
Y, X, Size: Integer;
Filestream: TFileStream;
ImageData: TMemoryStream;
PixelColor: TIEComplexColor;
begin //FTImage
try
FTImageCopy := ImageEnView1.Proc.FTCreateImage( ieitRGB ,-1,-1 );
ImageData := TMemoryStream.Create;
FileStream := TFileStream.Create(OriginalFileDir + '\FFT_' + ChangeFileExt(OriginalFileName, '.FTI'), fmCreate);
try
//Size would be (I think) Width x Height x 3(colors) x 2 (real & imag):
Size := FTImageCopy.ComplexWidth * FTImageCopy.ComplexHeight * 3 * 2;
ImageData.Write(Size, SizeOf(Integer));
ImageData.Write(FTImageCopy.Imagetype, SizeOf(TIEFtImageType));
ImageData.Write(FTImageCopy.ComplexWidth, SizeOf(Integer));
ImageData.Write(FTImageCopy.ComplexHeight, SizeOf(Integer));
try
for Y := 0 to FTImageCopy.ComplexHeight - 1 do
begin
for X := 0 to FTImageCopy.ComplexWidth - 1 do
begin
PixelColor := FTImageCopy.ComplexPixel[X, Y];
//Write Red:
ImageData.Write(PixelColor.real_Red, SizeOf(PIEsingle));
ImageData.Write(PixelColor.imag_Red, SizeOf(PIEsingle));
//Write Blue:
ImageData.Write(PixelColor.real_Blue, SizeOf(PIEsingle));
ImageData.Write(PixelColor.imag_Blue, SizeOf(PIEsingle));
//Write Green:
ImageData.Write(PixelColor.real_Green, SizeOf(PIEsingle));
ImageData.Write(PixelColor.imag_Green, SizeOf(PIEsingle));
end;
end;
finally
if(ImageData.Position > 0) then
begin
ImageData.Position := 0;
FileStream.CopyFrom(ImageData, 0);
end;
end;
finally
FileStream.Free;
FTImageCopy.Free;
end;
except
on E: Exception do
Writeln('Error: ', E.Message);
end;
end;
then another procedure that reads it back:
procedure TForm1.btnLoadFFTClick(Sender: TObject);
begin
if(OpenFFTAsBitmapDialog1.Execute) then
begin
try
if assigned(FTImage) then
FTImage.Free;
LoadFTImageFromFile(OpenFFTAsBitmapDialog1.FileName, FTImage);
if assigned(FTImage) then
begin
ImageEnView2.Proc.FTDisplayFrom(FTImage);
end;
finally
FTImage.Free;
end;
end;
end;
procedure TForm1.LoadFTImageFromFile(const FileName: String; var LoadedImage: TIEFTImage);
var
FileStream: TFileStream;
ImageData: TMemoryStream;
X, Y: Integer;
tmpImageEnView: TImageEnView;
ImageType: TIEFtImageType;
Size, Width, Height: Integer;
ExpectedSize: Integer;
begin
try
FileStream := TFileStream.Create(FileName, fmOpenRead);
ImageData := TMemoryStream.Create;
try
// Load data from the file into ImageData
ImageData.CopyFrom(FileStream, 0);
ImageData.Position := 0;
// Read the size of the data
ImageData.Read(Size, SizeOf(Integer));
// Read other metadata if needed
ImageData.Read(ImageType, SizeOf(TIEFtImageType));
ImageData.Read(Width, SizeOf(Integer));
ImageData.Read(Height, SizeOf(Integer));
//Temp:
tmpImageEnView := TImageEnView.Create(self);
LoadedImage := tmpImageEnView.Proc.FTCreateImage(ImageType, -1 -1);
try
// Load pixel data
for Y := 0 to Height - 1 do
begin
for X := 0 to Width - 1 do
begin
ImageData.Read(LoadedImage.ComplexPixel[X, Y].real_Red^, SizeOf(PIEsingle));
ImageData.Read(LoadedImage.ComplexPixel[X, Y].imag_Red^, SizeOf(PIEsingle));
ImageData.Read(LoadedImage.ComplexPixel[X, Y].real_Blue^, SizeOf(PIEsingle));
ImageData.Read(LoadedImage.ComplexPixel[X, Y].imag_Blue^, SizeOf(PIEsingle));
ImageData.Read(LoadedImage.ComplexPixel[X, Y].real_Green^, SizeOf(PIEsingle));
ImageData.Read(LoadedImage.ComplexPixel[X, Y].imag_Green^, SizeOf(PIEsingle));
end;
end;
// Now, you have the data loaded into LoadedImage
// You can use LoadedImage as needed
except
LoadedImage.Free;
raise; // Re-raise the exception
end;
finally
ImageData.Free;
FileStream.Free;
tmpImageEnView.Free;
end;
except
on E: Exception do
Writeln('Error: ', E.Message);
end;
end;
But I am getting I/O errors and access violation. |
|
|
drmoorejr
USA
7 Posts |
Posted - Oct 27 2023 : 13:39:11
|
I figured it out:
procedure TForm1.SaveFTImageToFile(const FileName: String);
var
Y, X, Size: Integer;
Filestream: TFileStream;
ImageData: TMemoryStream;
LoadedImage: TIEFTImage;
PixelColor: TIEComplexColor;
begin
try
case rgImgType.ItemIndex of
0: LoadedImage := ImageEnView1.Proc.FTCreateImage(ieitRGB, -1, -1);
1: LoadedImage := ImageEnView1.Proc.FTCreateImage(ieitGrayscale, -1, -1);
end;
ImageData := TMemoryStream.Create;
FileStream := TFileStream.Create(OriginalFileDir + '\FFT_' + ChangeFileExt(OriginalFileName, '.FTI'), fmCreate);
try
if(rgImgType.ItemIndex = 0) then
begin
//RGB Size would be (I think) Width x Height x 3(colors) x 2 (real & imag):
Size := LoadedImage.ComplexWidth * LoadedImage.ComplexHeight * 3 * 2;
end
else
begin
//Grayscale Size would be (I think) Width x Height x 1(colors) x 2 (real & imag):
Size := LoadedImage.ComplexWidth * LoadedImage.ComplexHeight * 1 * 2;
end;
ImageData.Write(Size, SizeOf(Integer));
ImageData.Write(LoadedImage.Imagetype, SizeOf(TIEFtImageType));
ImageData.Write(LoadedImage.ComplexWidth, SizeOf(Integer));
ImageData.Write(LoadedImage.ComplexHeight, SizeOf(Integer));
try
for Y := 0 to LoadedImage.ComplexHeight - 1 do
begin
for X := 0 to LoadedImage.ComplexWidth - 1 do
begin
PixelColor := LoadedImage.ComplexPixel[X, Y];
case LoadedImage.Imagetype of
ieitRGB:
begin
//Write Red:
ImageData.Write(PixelColor.real_Red^, SizeOf(Single));
ImageData.Write(PixelColor.imag_Red^, SizeOf(Single));
//Write Green:
ImageData.Write(PixelColor.real_Green^, SizeOf(Single));
ImageData.Write(PixelColor.imag_Green^, SizeOf(Single));
//Write Blue:
ImageData.Write(PixelColor.real_Blue^, SizeOf(Single));
ImageData.Write(PixelColor.imag_Blue^, SizeOf(Single));
end;
ieitGrayscale:
begin
//Write Gray:
ImageData.Write(PixelColor.real_gray^, SizeOf(Single));
ImageData.Write(PixelColor.imag_gray^, SizeOf(Single));
end;
end;
end;
end;
finally
if(ImageData.Position > 0) then
begin
ImageData.Position := 0;
FileStream.CopyFrom(ImageData, 0);
end;
end;
finally
FileStream.Free;
ImageData.Free;
end;
except
on E: Exception do
Writeln('Error: ', E.Message);
end;
end;
and
procedure TForm1.LoadFTImageFromFile(const FileName: String);
var
FileStream: TFileStream;
ImageData: TMemoryStream;
tmpSingle: Single;
X, Y: Integer;
ImageType: TIEFtImageType;
Size, Width, Height: Integer;
ExpectedSize: Integer;
begin
try
FileStream := TFileStream.Create(FileName, fmOpenRead);
ImageData := TMemoryStream.Create;
try
// Load data from the file into ImageData
ImageData.CopyFrom(FileStream, 0);
ImageData.Position := 0;
// Read the size of the data
ImageData.Read(Size, SizeOf(Integer));
// Read other metadata if needed
ImageData.Read(ImageType, SizeOf(TIEFtImageType));
ImageData.Read(Width, SizeOf(Integer));
ImageData.Read(Height, SizeOf(Integer));
//Temp:
FTImage := ImageEnView1.Proc.FTCreateImage(ImageType, Width, Height);
try
// Load pixel data
for Y := 0 to Height - 1 do
begin
for X := 0 to Width - 1 do
begin
case ImageType of
ieitRGB:
begin
//Read real_Red:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage.ComplexPixel[X, Y].real_Red^ := tmpSingle;
//Read imag_Red:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage.ComplexPixel[X, Y].imag_Red^ := tmpSingle;
//Read real_Green:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage.ComplexPixel[X, Y].real_Green^ := tmpSingle;
//Read imag_Green:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage.ComplexPixel[X, Y].imag_Green^ := tmpSingle;
//Read real_Blue:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage.ComplexPixel[X, Y].real_Blue^ := tmpSingle;
//Read imag_Blue:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage.ComplexPixel[X, Y].imag_Blue^ := tmpSingle;
end;
ieitGrayscale:
begin
//Read real_gray:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage.ComplexPixel[X, Y].real_gray^ := tmpSingle;
//Read imag_gray:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage.ComplexPixel[X, Y].imag_gray^ := tmpSingle;
end;
end;
end;
end;
// Now, you have the data loaded into LoadedImage
// You can use LoadedImage as needed
except
raise; // Re-raise the exception
end;
finally
ImageData.Free;
FileStream.Free;
//tmpImageEnView.Free;
end;
except
on E: Exception do
Writeln('Error: ', E.Message);
end;
end; |
|
|
xequte
38611 Posts |
Posted - Oct 27 2023 : 19:55:23
|
Hi David
Please email me. I'll implement methods to load and save the FFT.
Nigel Xequte Software www.imageen.com
|
|
|
drmoorejr
USA
7 Posts |
Posted - Dec 22 2023 : 10:01:20
|
Hi, sorry for the delay. I will email you the code. Also we figured out another enhancement to the FFT stuff that you may find useful. But still working on one remaining item. But we were using the Demo stuff and are ready to purchase the product but we have a few questions regard the license purchase for 2 developers (ImageEN & IEVision) with source code. There are two of use that develop software, but we sometimes have to install the IDE on a system connected to a machine, and I wold like to know what the installation limits are with the software. |
|
|
drmoorejr
USA
7 Posts |
Posted - Dec 22 2023 : 10:58:07
|
Obviously this was for a specific purpose so the second method below could be cleaned up.
procedure TForm1.SaveFTImageToFile(const FileName: String);
var
Y, X, Size: Integer;
Filestream: TFileStream;
ImageData: TMemoryStream;
LoadedImage: TIEFTImage;
PixelColor: TIEComplexColor;
begin
try
case rgImgType.ItemIndex of
0: LoadedImage := ImageEnView1.Proc.FTCreateImage(ieitRGB, -1, -1);
1: LoadedImage := ImageEnView1.Proc.FTCreateImage(ieitGrayscale, -1, -1);
end;
ImageData := TMemoryStream.Create;
FileStream := TFileStream.Create(OriginalFileDir + '\FFT_' + ChangeFileExt(OriginalFileName, '.FTI'), fmCreate);
try
case rgImgType.ItemIndex of
0:
begin
//Size would be (I think) Width x Height x 3 (colors) x 2 (real & imag):
Size := LoadedImage.ComplexWidth * LoadedImage.ComplexHeight * 3 * 2;
end;
1:
begin
//Size would be (I think) Width x Height x 1 (color) x 2 (real & imag):
Size := LoadedImage.ComplexWidth * LoadedImage.ComplexHeight * 1 * 2;
end;
end;
ImageData.Write(Size, SizeOf(Integer));
ImageData.Write(LoadedImage.Imagetype, SizeOf(TIEFtImageType));
ImageData.Write(LoadedImage.ComplexWidth, SizeOf(Integer));
ImageData.Write(LoadedImage.ComplexHeight, SizeOf(Integer));
try
for Y := 0 to LoadedImage.ComplexHeight - 1 do
begin
for X := 0 to LoadedImage.ComplexWidth - 1 do
begin
PixelColor := LoadedImage.ComplexPixel[X, Y];
case LoadedImage.Imagetype of
ieitRGB:
begin
//Write Red:
ImageData.Write(PixelColor.real_Red^, SizeOf(Single));
ImageData.Write(PixelColor.imag_Red^, SizeOf(Single));
//Write Green:
ImageData.Write(PixelColor.real_Green^, SizeOf(Single));
ImageData.Write(PixelColor.imag_Green^, SizeOf(Single));
//Write Blue:
ImageData.Write(PixelColor.real_Blue^, SizeOf(Single));
ImageData.Write(PixelColor.imag_Blue^, SizeOf(Single));
end;
ieitGrayscale:
begin
//Write Gray:
ImageData.Write(PixelColor.real_gray^, SizeOf(Single));
ImageData.Write(PixelColor.imag_gray^, SizeOf(Single));
end;
end;
end;
end;
finally
if(ImageData.Position > 0) then
begin
ImageData.Position := 0;
FileStream.CopyFrom(ImageData, 0);
end;
end;
finally
FileStream.Free;
ImageData.Free;
end;
except
on E: Exception do
Writeln('Error: ', E.Message);
end;
end;
This is the read (like I said above its for comparing two images one a model and one an actual photo), so it could be made more generic.
procedure TForm1.LoadFTImageFromFile(const FileName: String; ModelOrActual: Integer);
var
FileStream: TFileStream;
ImageData: TMemoryStream;
tmpSingle: Single;
X, Y: Integer;
ImageType: TIEFtImageType;
Size, Width, Height: Integer;
ExpectedSize: Integer;
begin
try
FileStream := TFileStream.Create(FileName, fmOpenRead);
ImageData := TMemoryStream.Create;
try
// Load data from the file into ImageData
ImageData.CopyFrom(FileStream, 0);
ImageData.Position := 0;
// Read the size of the data
ImageData.Read(Size, SizeOf(Integer));
// Read other metadata if needed
ImageData.Read(ImageType, SizeOf(TIEFtImageType));
ImageData.Read(Width, SizeOf(Integer));
ImageData.Read(Height, SizeOf(Integer));
//Temp:
Case ModelOrActual Of
LOAD_MODEL: FTImage_Model := Model_ImageEnView.Proc.FTCreateImage(ImageType, Width, Height);
LOAD_ACTUAL: FTImage_Actual := Actual_ImageEnView.Proc.FTCreateImage(ImageType, Width, Height);
End;
try
// Load pixel data
for Y := 0 to Height - 1 do
begin
for X := 0 to Width - 1 do
begin
case ImageType of
ieitRGB:
begin
Case ModelOrActual Of
LOAD_MODEL:
begin
//Read real_Red:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Model.ComplexPixel[X, Y].real_Red^ := tmpSingle;
//Read imag_Red:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Model.ComplexPixel[X, Y].imag_Red^ := tmpSingle;
//Read real_Green:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Model.ComplexPixel[X, Y].real_Green^ := tmpSingle;
//Read imag_Green:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Model.ComplexPixel[X, Y].imag_Green^ := tmpSingle;
//Read real_Blue:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Model.ComplexPixel[X, Y].real_Blue^ := tmpSingle;
//Read imag_Blue:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Model.ComplexPixel[X, Y].imag_Blue^ := tmpSingle;
end;
LOAD_ACTUAL:
begin
//Read real_Red:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Actual.ComplexPixel[X, Y].real_Red^ := tmpSingle;
//Read imag_Red:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Actual.ComplexPixel[X, Y].imag_Red^ := tmpSingle;
//Read real_Green:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Actual.ComplexPixel[X, Y].real_Green^ := tmpSingle;
//Read imag_Green:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Actual.ComplexPixel[X, Y].imag_Green^ := tmpSingle;
//Read real_Blue:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Actual.ComplexPixel[X, Y].real_Blue^ := tmpSingle;
//Read imag_Blue:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Actual.ComplexPixel[X, Y].imag_Blue^ := tmpSingle;
end;
End;
end;
ieitGrayscale:
begin
Case ModelOrActual Of
LOAD_MODEL:
begin
//Read real_gray:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Model.ComplexPixel[X, Y].real_gray^ := tmpSingle;
//Read imag_gray:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Model.ComplexPixel[X, Y].imag_gray^ := tmpSingle;
end;
LOAD_ACTUAL:
begin
//Read real_gray:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Actual.ComplexPixel[X, Y].real_gray^ := tmpSingle;
//Read imag_gray:
ImageData.Read(tmpSingle, SizeOf(Single));
FTImage_Actual.ComplexPixel[X, Y].imag_gray^ := tmpSingle;
end;
End;
end;
end;
end;
end;
// Now, you have the data loaded into LoadedImage
// You can use LoadedImage as needed
except
raise; // Re-raise the exception
end;
finally
ImageData.Free;
FileStream.Free;
//tmpImageEnView.Free;
end;
except
on E: Exception do
Writeln('Error: ', E.Message);
end;
end; |
|
|
xequte
38611 Posts |
Posted - Dec 22 2023 : 14:25:40
|
> There are two of use that develop software, but we sometimes have to install the IDE on a system connected to a machine
Licenses are sold per developer, so this scenario would only require two licenses.
Nigel Xequte Software www.imageen.com
|
|
|
|
Topic |
|
|
|