簡體   English   中英

將圖像從.NET傳輸到Delphi

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM