我想知道有没有人能给我建议。我编写了一个.NET 4 WCF服务,该服务旨在为扫描文档提供服务,并且很难让Delphi7用户工作。
在.NET方面,我使用以下代码将图像转换为位图,然后转换为字节数组:
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是不是太过时了,无法处理现代位图?服务器端的文件是相关的吗?接下来我该怎么办?
感激地收到任何建议。
更新
我修改了代码,以便传递一个JPG,结果非常相似。这一次,当我尝试加载图像客户端时,我得到了JPEG错误53。如果我使用TFileStream并将其保存到磁盘,则的结果文件看起来很好,但仍然不会加载到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;
}
} 发布于 2012-08-17 18:09:53
除非您可以继续使用位图图像,否则您可能需要尝试通过TJPegImage (从JPeg单元中读取)从流中读取图像。我正在做一些类似于您正在尝试的事情,但是通过AtoZed的“.Net”产品从.Net图像库的包装器直接获得图像字节。
因此,首先,我必须将传递到边界的.Net MemoryStream对象转换为Delphi字节数组。然后,我将其加载到Delphi TMemoryStream中,并将其放入TJpegImage中。
(一开始我遇到了与您相同的问题,直到我决定LoadfromFile显然是在根据文件名定制加载方式。在此基础上,我显式地为JPegs、Tiffs等创建了适当的映像变体,而不是试图将其加载为一般的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;发布于 2012-08-11 01:31:03
我的印象是,您让WCF负责服务器和客户端之间的数据编组和序列化过程(都是通过工具为您自动生成的?)而且你对“在线”格式并没有太多的控制,现在你想用Delphi 7编写一个客户端,它可以读取这些信息。
我将警告您,您正面临一场艰苦的斗争,但是如果您的WCF正在使用SOAP消息,那么您就有机会在Delphi中编写一个SOAP客户端,它将消耗您的WCF服务的消息。
至于图像本身,我不知道它们是如何序列化的。但一旦你发现了应该很容易。假设WCF不是简单地序列化System.Drawing.Bitmap,而是在磁盘上传输位图文件的原始字节,那么您就都设置好了:只需将WCF消息的字节转储到磁盘或内存中的缓冲区,然后使用TBitmap打开它们。
发布于 2012-08-16 17:40:57
抱歉,大家-这原来是条红鲱鱼。问题是,我提供的图像一开始是无效的。给第三方供应商打个电话就足够了。
从好的方面来说,这意味着我提供的代码示例基本上是正确的。
https://stackoverflow.com/questions/11911073
复制相似问题