如何將“ TJpegImage的 Array[0..9] ”保存并加載到MemoryStream。有很多樣本可以將一張影像保存到流中,但沒有人保存陣列。我需要它將 Stream 保存到資料庫 Blob 欄位,然后將 BlobField 加載回我的陣列。陣列中的所有影像具有相同的大小。也許 TByte 流可以做到這一點?但是如何將 TByte-Stream 轉換回陣列呢?
更新:非常感謝 MBo 的示例。我嘗試使用它并遇到一些問題。我使用 Paintbox 繪制圖片并在 0x0062b9ab:read of address 0x000 處獲得訪問沖突......
這是我嘗試的代碼:
單元 PicToMemStream;界面
使用 Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、System.Classes、Vcl.Graphics、Vcl.Controls、Vcl.Forms、Vcl.Dialogs、Vcl.Imaging.jpeg、Vcl.ExtCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
PaintBox: TPaintBox;
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
ms, temp: TMemoryStream;
jps: array of TJpegImage;
i, n, sz: Integer;
ProgPath: String;
begin
ProgPath := ExtractFilePath(Application.ExeName);
n := 3;
SetLength(jps, n);
ms := TMemoryStream.Create;
temp := TMemoryStream.Create;
for i := 0 to n - 1 do
begin
jps[i] := TJpegImage.Create;
jps[i].LoadFromFile(Format(ProgPath '%s.jpg', [Chr(Ord('a') i)]));
// in my case loads files a.jpg, b.jpg, c.jpg
end;
// Save Pictures to Stream and later in BlobField (100kByte)
try
ms.Write(n, SizeOf(n));
for i := 0 to n - 1 do
begin
temp.Clear;
// Save Image Data first here
jps[i].SaveToStream(temp); // jpeg data here
sz := temp.Size;
// Save length second here
ms.Write(sz, SizeOf(sz)); // size of image
temp.Position := 0;
ms.CopyFrom(temp, sz); // image data to final destination
end;
ms.SaveToFile(ProgPath 'base.dat'); // for control // later here Write Data to BLob
// Read Picture and show it in a Paintbox or Image
// revert to empty stream
ms.Clear;
ms.LoadFromFile(ProgPath 'base.dat'); // load from "base" // later here Read Data from Blob
ms.Read(n, SizeOf(n));
// here some actions to setup array
for i := 0 to n - 1 do // Read 3 times a picture
begin
ms.Read(sz, SizeOf(sz)); // Read Lenth of Picturedata first
temp.Clear; // Read Picturedata in jps[i]
temp.CopyFrom(ms, sz);
temp.Position := 0;
jps[i].LoadFromStream(temp);
Form1.PaintBox.Canvas.Draw(0, 0, jps[i]); // Show Picture with Error
//Form1.Image1.Picture.Bitmap.LoadFromStream(temp);
Sleep(2000); // To see the Picture for 2 seconds (Test)
end;
finally
ms.Free;
temp.Free;
for i := 0 to n - 1 do
jps[i].Free;
end;
end.
Update2:我將代碼放在一個 ButtonClick 程序中并更改:
temp.Position := 0;
jps[i].LoadFromStream(temp);
Form1.PaintBox.Canvas.Draw(0, 0, jps[i]); // Show Picture in Paintbox
Form1.Image1.Picture.Assign(jps[i]); // Show Picture in TImage
Application.ProcessMessages;
Sleep(500); // To see the Picture for 2 seconds (Test)
end;
我還將使用 Master-Detail Table 或 TFDMemTable 或 Encoding to Text 測驗其他想法,看看什么對我來說是最好的。感謝所有幫手。
uj5u.com熱心網友回復:
All Images in the Array has the same Size- 也許尺寸(寬度/高度)相同,但 jpeg 影像的大小(以位元組為單位)因圖片和壓縮而異。所以我假設您需要存盤影像資料和資料大小。
可能的方法:
- 將整數值 - 陣列長度 - 寫入記憶體流
ms - 對于每個陣列元素,將其保存到臨時記憶體流
temp_ms - 將整數值寫入
sz = ms.size主記憶體流ms - 重置
temp_ms.Position為 0 CopyFrom將 ( )sz個位元組從temp_msto復制到ms- 清除
temp_ms - 對所有陣列元素重復
現在ms內容看起來像:
10 14212 FFD8....D9 31234 FFD8....D9
10 images
1st image size
1st image contents
2nd image size
2nd image contents
要檢索影像,請執行相反的操作:
- 重置
ms位置(如果需要) n從中讀取影像數量ms- 設定陣列大小(如果陣列是動態的)
n次:- 讀取影像大小
sz sz將位元組復制到temp_ms- 重置
temp_ms.Position array[i]從加載temp_ms
作業示例:
var
ms, temp: TMemoryStream;
jps: array of TJpegImage;
i, n, sz: Integer;
begin
n := 3;
SetLength(jps, n);
ms := TMemoryStream.Create;
temp := TMemoryStream.Create;
for i := 0 to n - 1 do begin
jps[i] := TJpegImage.Create;
jps[i].LoadFromFile(Format('h:\%s.jpg', [Chr(Ord('a') i)]));
//in my case loads files a.jpg, b.jpg, c.jpg
end;
try
ms.Write(n, SizeOf(n));
for i :=0 to n - 1 do begin
temp.Clear;
jps[i].SaveToStream(temp); //jpeg data here
sz := temp.Size;
ms.Write(sz, SizeOf(sz)); //size of image
temp.Position := 0;
ms.CopyFrom(temp, sz); //image data to final destination
end;
ms.SaveToFile('h:\base.dat'); //for control
//revert to empty stream
ms.Clear;
ms.LoadFromFile('h:\base.dat'); //load from "base"
ms.Read(n, SizeOf(n));
//here some actions to setup array
for i :=0 to n - 1 do begin
ms.Read(sz, SizeOf(sz));
temp.Clear;
temp.CopyFrom(ms, sz);
temp.Position := 0;
jps[i].LoadFromStream(temp);
Canvas.Draw(i * 200, 0, jps[i]); //control shot
end;
finally
ms.Free;
temp.Free;
for i := 0 to n - 1 do
jps[i].Free;
end;
uj5u.com熱心網友回復:
為什么不使用 TFDMemTable?
另一個選項可以是,使用 System.NetEncoding.TNetEncoding.Base64 編碼的 TStringList,因為 TStringList 非常像一個超級向量
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/484634.html
上一篇:如何確定陣列中最常出現的數字?
