[英]Transferring Images from .NET to Delphi
我想知道是否有人可以提供建議。 我編寫了一個.NET 4 WCF服務,旨在提供掃描文檔,並努力讓Delphi 7消費者工作。
在.NET端,我使用以下代碼將Images轉換為Bitmaps,然后轉換為Byte Arrays。
using (Bitmap img = new Bitmap(fileName))
{
ImageConverter converter = new ImageConverter();
_bytes = (byte[])converter.ConvertTo(img, typeof(byte[]));
}
在消費者方面,我想將ByteArray讀入TImage.Picture,這就是計划失敗的地方。 “LoadFromStream”行中的以下代碼錯誤
EInvalidGraphic,消息“位圖圖像無效”
procedure TBarcodeImageForm.FetchFile;
var
bytes : TByteDynArray;
info : TDocInfo;
Stream : TMemoryStream;
bmp : TBitMap;
begin
info := TDocInfo(FDocList.Items[lbFIles.ItemIndex]);
bytes := FDocButton.FetchDocument(info.FilePath).Data;
stream := TMemoryStream.Create();
try
Stream.Write(bytes[0], Length(Bytes));
Stream.Position := 0;
bmp := TBitMap.Create;
bmp.LoadFromStream(stream);
finally
Stream.Free;
end;
end;
通過使用TFileStream代替上面的內存流,我已經證明數據是有效的 - 也就是說我可以在MSPaint中加載結果。 我不得不承認我被困在下一步:Delphi 7是否過時了處理現代位圖? 事實上,服務器端的文件是tiffs和jpgs相關嗎? 接下來我該怎么辦?
任何建議都感激不盡。
更新-------------------
我更改了代碼,以便傳遞JPG並且結果非常相似。 這次我嘗試加載圖像客戶端時出現JPEG錯誤#53。 如果我使用TFileStream並保存到磁盤,結果文件在Windows Picture Viewer中看起來很好,但仍然無法加載到TImage組件中。
客戶端現在看起來像這樣
stream := TFileStream.Create('c:\temp.jpg', fmCreate);
try
Stream.Write(bytes[0], Length(Bytes));
Stream.Position := 0;
finally
Stream.Free;
end;
try
imgDocument.Picture.LoadFromFile('c:\temp.jpg');
except end;
服務器端(這次發布整個數據合同以防萬一)
[DataContract]
public class ImageData
{
private byte[] _bytes;
[DataMember]
public byte[] Data
{
get { return _bytes; }
set { _bytes = value; }
}
public ImageData(string fileName)
{
using (MemoryStream memStream = new MemoryStream())
{
using (Image img = Image.FromFile(fileName))
{
img.Save(memStream, ImageFormat.Jpeg);
}
_bytes = new Byte[memStream.Length];
int i = 0;
while (i < memStream.Length)
i += memStream.Read(_bytes, i, 128000);
}
}
}
更新------------------------------------------------- ----------------
從Winforms使用者成功測試服務使用了以下代碼。
if (docList != null)
{
using (MemoryStream memStream =
new MemoryStream(client.FetchDocument(docList.Items[0].FilePath).Data))
{
System.Drawing.Image img = Image.FromStream(memStream);
pictureBox1.Image = img;
}
}
我得到的印象是,你正在讓WCF負責在服務器和客戶端之間進行編組和序列化數據的過程(兩者都是由工具自動生成的?)而且你實際上並沒有太多的控制權。 “on-the-wire”格式,現在你想在Delphi 7中編寫一個可以讀取它的客戶端。
我會警告你,你正在努力奮斗,但如果你的WCF正在使用SOAP消息,那么你就有機會在Delphi中編寫一個消耗你的WCF服務消息的SOAP客戶端。
至於圖像本身,我不知道它們是如何序列化的。 但是一旦你發現它應該很容易。 假設WCF不是簡單地序列化System.Drawing.Bitmap而是在磁盤上傳輸Bitmap文件的原始字節,那么你就全部設置:只需將WCF消息的字節轉儲到磁盤或內存緩沖區並打開他們使用TBitmap。
對不起,大家 - 原來是紅鯡魚。 問題是我服務的圖像首先是無效的。 只需快速撥打第三方供應商的電話即可。
在正面,這意味着我提供的代碼示例基本上是合理的。
除非你可以保留Bitmap圖像,否則你可能想嘗試通過TJPegImage(從JPeg單元中)讀取流中的圖像。 我正在做類似於你正在嘗試的事情,但我通過AtoZed的“CrossTalk”產品從.Net 4包裝器直接獲取圖像字節.Net成像庫。
所以首先我必須將跨越邊界的.Net MemoryStream對象轉換為Delphi的byte數組。 然后我將它加載到Delphi TMemoryStream中並將其帶入TJpegImage。
(我最初遇到了同樣的問題,直到我確定LoadfromFile顯然正在根據文件名定制加載的方式。基於此,我明確地為JPegs,Tiff等創建了正確的圖像變體而不是嘗試將其作為通用TImage加載。)
當返回的圖像是Jpeg時,這適用於Delphi7:
dJpegImage: TJpegImage;
imageMemoryStream: MemoryStream;
pictureBoxImageOutput: TImage;
lengthImageByteArray: Integer; // already set before this fragment based on the .Net Image info
imageDelphiByteArray: array of byte;
...
...
imageStream := TMemoryStream.Create();
imageStream.WriteBuffer(imageDelphiByteArray[0], lengthImageByteArray);
imageStream.Position := 0;
dJpegImage := TJPEGImage.Create;
dJpegImage.LoadFromStream(imageStream);
pictureBoxImageOutput.Picture.Graphic := dJpegImage;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.