2012-08-11 6 views
1

누구든지 조언 할 수 있는지 궁금합니다. 필자는 스캔 한 문서를 제공하기위한 .NET 4 WCF 서비스를 작성했으며 델파이 7 소비자가 작업하기 위해 고심하고 있습니다. 나는 TImage.Picture로 된 ByteArray를 읽고 싶은 소비자 측면에서.NET에서 Delphi로 이미지 전송

 using (Bitmap img = new Bitmap(fileName)) 
     { 
      ImageConverter converter = new ImageConverter(); 
      _bytes = (byte[])converter.ConvertTo(img, typeof(byte[])); 
     } 

이 : 나는 비트 맵에 다음 코드를 사용하여 바이트의 배열로 이미지를 변환하고있는 .NET 측면에서

계획이 세워진 곳입니다. 내가 보여준 위

EInvalidGraphic 메시지와 함께 'LoadFromStream'라인에 다음 코드 오류 메모리 스트림 대신에 TFileStream을 사용함으로써

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; 

'비트 맵 이미지가 유효하지 않습니다' 데이터가 유효하다는 것입니다. 즉 MSPaint에서 결과를로드 할 수 있습니다. 나는 다음 단계로 나아갈 수밖에 없다는 것을 인정해야한다 : 델파이 7은 현대의 비트 맵을 처리하기에는 구형인가? 사실 서버 측의 파일은 tiff이고 jpg는 관련이 있습니까? 다음에 무엇을해야합니까?

감사의 말을 전합니다. jpg이가 건너 전달되는되었고, 그 결과가 매우 유사 있도록

UPDATE는 -------------------

나는 코드를 변경. 이번에는 이미지를 클라이언트 측에서로드하려고 시도 할 때 JPEG 오류 # 53이 발생합니다. TFileStream을 사용하고 디스크에 저장하면 결과 파일은 Windows Picture Viewer에서 잘 보이지만 TImage 구성 요소에는로드되지 않습니다.

클라이언트 측 지금 -----------

[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); 
     } 
    } 
} 

UPDATE (전체 데이터 계약의 경우이 시간을 게시)이

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; 

서버 측 같습니다 -------------------------------------------------- ----

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; 
    } 
} 
+0

그것은 항상 문제가 실제로 무엇을 게시하는 데 도움이 :이 Delphi7 나를 위해 일하는 대신 일반 TImage의로로드하려고의)

이미지가 반환되는 경우는 이펙이었다. 코드를 기반으로한다면, 가지고있는 것을 보여주십시오. 디자인을 기반으로한다면, 생각하고있는 것을 말해주십시오. – NotMe

+0

나는 준비가되기 오래 전부터 질문을 던졌습니다. –

+0

@Ken White - 예 사과 –

답변

1

Bitmap 이미지를 사용하는 것이 좋으면 TJPegImage (JPeg 유닛 밖)를 통해 이미지를 스트림에서 읽을 수 있습니다. 당신이 시도하고있는 것과 비슷한 것을하고 있지만, AtoZed의 "CrossTalk"제품을 통해 .NET 이미징 라이브러리 주위의 .Net 4 래퍼에서 이미지 바이트를 직접 가져옵니다.

그래서 먼저 경계를 넘어 델파이 배열로 전달 된 .Net MemoryStream 객체를 변환해야합니다. 그런 다음 Delphi TMemoryStream에로드하고 TJpegImage로 가져옵니다.

(처음에는 LoadfromFile이 파일 이름을 기반으로로드가 수행되는 방식을 결정할 때까지 동일한 문제가 발생했습니다. 그 점을 고려하여 JPegs, Tiffs 등의 이미지 변형을 명시 적으로 만들었습니다. ..

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; 
+0

그 점에 대해 고마워요. 클라이언트 측이 지금 어떻게 보이는지 알 수 있습니다. 분명히 디스크 클라이언트 측을 공격하지 않는 것이 좋습니다. –

1

나는 당신이 (두 도구에 의해 당신을 위해 자동이 생성?) 서버와 클라이언트 사이에 정렬 화하는 과정의 관리 및 serialising 데이터를 취할 WCF를 받고있는 인상을 당신은 '돈 있음 "on-the-wire"형식에 대한 많은 제어권을 가지고 있으며 이제는 이것을 읽을 수있는 클라이언트를 Delphi 7에 작성하려고합니다.

나는 당신이 힘든 투쟁을하고 있다고 경고 하겠지만 WCF가 SOAP 메시지를 사용한다면 당신은 WCF를 소비하는 델파이에서 SOAP 클라이언트를 작성할 수 있어야한다. 서비스의 메시지.

이미지 자체에 관해서는 어떻게 연재되었는지는 모르겠다. 그러나 일단 당신이 발견하면 그것은 쉬워야합니다. WCF가 단순히 System.Drawing.Bitmap을 직렬화하는 대신 Bitmap 파일의 원시 바이트를 디스크에 전송한다고 가정하면 모든 설정이 완료됩니다. WCF 메시지의 바이트를 디스크 나 메모리 버퍼에 덤프하고 열기 만하면됩니다. TBitmap을 사용합니다.

+0

데이터 계약을 지정하는 데 아주 신중을 기했습니다. 'fetchFile'메서드는 바이트 배열을 반환합니다. 나는 나의 모든 다른 방법들이 달콤하게 일하고있다. 델파이 측에서는 wsdlImp를 사용하여 인터페이스를 만들었지 만 수신 된 데이터가 기대 한 것임을 확신합니다. 즉, 게시물에서 말했듯이 수신 된 스트림을 파일에 저장하면 완벽하게 좋은 그래픽입니다. –

+0

당신의 세 번째 문단은 제 문제를 요약합니다 - 그것은 아주 힘들어 야합니다,하지만 그것은 작동하지 않습니다. 예 SOAP을 사용하고 있습니다. –

+0

문제는 델파이의 비트 맵 지원이 아니라 WCF-Delphi-SOAP-RTL 임피던스 불일치입니다. Delphi의 SOAP RTL은 모든 가능한 WCF API 서명 (데이터 계약이라고 부름)을 완벽하게 처리 할 수 ​​없습니다. 나는 그것을 어떻게 할 수 있었으면 좋겠어. –

1

죄송합니다. 누구나 - 이것은 붉은 청어로 밝혀졌습니다.문제는 제가 게재 한 이미지가 처음부터 유효하지 않다는 것이 었습니다. 제 3 자 공급 업체에 대한 신속한 전화 통화가 모두 필요했습니다.

더하기 쪽에서는 내가 제공 한 코드 샘플이 기본적으로 소리가 나는 것을 의미합니다.