Delphi 读取 c# webservice XML的base64编码图片字符串转化图片并显示

Delphi 读取 c# webservice XML的base64编码图片字符串转化图片并显示

在 开发中遇到应用c#及asp.net的在的webservice 保存图片并以xml文件形式现实出来 并用delphi调用

的方法:
.c#的webservice现实见
http://www.greensoftcode.net/techntxt/20127118441582992373 之前的文章。
.在客户端用delphi显示 发现asp.net xml形式输出的图片是base64字符串形式。用delphi解析很困难
所以这里我先用c#解析读取图片并显示 然后在用delphi显示主要看看显示的xml图片是否可以显示。 c#的代码是:
private void button1_Click(object sender, System.EventArgs e)
{
long len;
byte[] byt = new byte[] { 0x00 };
//string base64String=Convert.ToBase64String(this.textBox1.Text);
byt=Convert.FromBase64String(this.textBox1.Text);
string str = System.Text.Encoding.Default.GetString( byt ); System.IO.MemoryStream ms=new System.IO.MemoryStream();
ms.Write(byt, , byt.Length) ;
ms.Seek(, System.IO.SeekOrigin.Begin) ;
len=ms.Length;
pictureBox1.Image = Image.FromStream(ms) ; }
图片显示没有问题!这就证明啦asp.net webservice 以XML字符串显示图片没有问题 ,只要delphi的 算法正确就可以。
.下面用delphi实现说实话我研究啦很长时间终于研究出来啦 结果见: 先引用 EncdDecd单元 EncdDecd单元是delphi自带的
uses EncdDecd
var ss:TStringStream;
ms:TMemoryStream;
JpgFile:TjpegImage ;
begin
ss:=TStringStream.Create(Memo1.Text);
ms:=TMemoryStream.Create;
DecodeStream(ss,ms);
ms.Position:=;
JpgFile:=TjpegImage.Create ;
JpgFile.LoadFromStream(ms);
ss.Free;
ms.Free;
Image1.Picture.Bitmap.Assign(JpgFile);
end;
就这样就可以读出c#的webservice 的图片文件
  • delphi读取asp.net webservice 中dataset数据集数据的的方法,并且与dbgrid的绑定
delphi读取asp.net webservice 中dataset数据集数据的的方法并且与dbgrid的绑定
delphi 访问c#中webservice 的函数如果不带dataset数据表那么不是很复杂!
如果访问返回表的函数相对就复杂啦些! 下面我讲下如何用delphi访问c#些的webservice函数 .web端函数为:
[WebMethod]
public string gettable(int pageIndex , int pageSize , out int recordCount, out int pageCount ,string keyword)
{
recordCount=;
pageCount=;
DataTable tb=null;
DataSet ds=new DataSet();
if (Validate())
{
try
{
a App=new Pa() ;
tb=App.gettable( pageIndex , pageSize , out recordCount, out pageCount , keyword );
}
catch
{ }
ds.Tables.Add(tb); }
//这里不要return ds; 因为delphi识别C#的webservice函数XMl文档很费劲 所以采用下面的方法
System.Text.StringBuilder strbuilder=new System.Text.StringBuilder();
StringWriter writer=new StringWriter(strbuilder);
ds.WriteXml(writer,System.Data.XmlWriteMode.IgnoreSchema);
return strbuilder.ToString(); }
.客户端
SOAP定义端
procedure Sev_gettable(const pageIndex: Integer; const pageSize: Integer; const keyword: WideString;
out gettableResult: WideString; out recordCount: Integer; out pageCount: Integer); stdcall;
//注意这是个过程不是函数 它的返回值是通过OUT输出参数做到的。 soap定义可以通过DELPHI建立 FILE-new-other-webservice -wsdl impoerts建立这个类把这个类文件加载到你的工程里就OK啦 function Sev_gettable(const pageIndex: Integer; const pageSize: Integer; const keyword: WideString,out recordCount: Integer; out pageCount: Integer): WideString;
var
HTTPRio : THTTPRIO ;
Ahttprio: ClientServiceSoap; val: WideString;
begin
HTTPRio:= THTTPRIO.Create(Application);
Try
HTTPRio.WSDLLocation:=''http://www.xxx.com/abc/getab.asmx?wsdl'';
Ahttprio := (HTTPRio as Cli entServiceSoap);
Ahttprio.gettable( pageIndex, pageSize,keyword,val, recordCount, pageCount) ;
Ahttprio:=nil;
Pointer(Ahttprio) := nil;
soapHeader.Free;
finally
End;
Result:=val;
End; 那么通过上面的函数我们可以获得xml数据集文档
下面就对这个文档进行分析与数据的提取
我们建立一个FORM1在上面加入 Tstringlist控件 为什么用 Tstringlist控件不用Tdbgrid能 因为 Tstringlist可以*的编写行和列 与tdbgrid绑定数据表效果一样
看实现函数 //读取xml数据集到stringlist中
//这个xmlstr参数 就是我们上面函数 Sev_gettable获得asp.ent webservice 返回的数据集 procedure iningrd(strdrg:TStringGrid;xmlstr:string);
var
fieldval: string;
node: IXMLNode;
XMLDoc:TXMLDocument;
nodeList: IXMLNodeList;
nodecount,i,j:integer; begin
for i:= to strdrg.rowcount- do
for j:= to strdrg.colcount- do
strdrg.Cells[j,i]:= '';
strdrg.Cells[,]:='编号';
strdrg.Cells[,]:='类型';
strdrg.Cells[,]:='状态';
strdrg.Cells[,]:='工号';
strdrg.Cells[,]:='姓名';
strdrg.Cells[,]:='电话';
strdrg.Cells[,]:='所收';
strdrg.Cells[,]:='姓名';
strdrg.Cells[,]:='电话';
strdrg.Cells[,]:='姓名';
strdrg.Cells[,]:='电话';
strdrg.Cells[,]:='所属';
strdrg.Cells[,]:='日期';
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
strdrg.ColWidths[]:=;
XMLDoc:=TXMLDocument.Create(Application);
XMLDoc.XML.Text:=xmlstr;
XMLDoc.Active:=true;
nodecount:=XMLDoc.DocumentElement.ChildNodes.Count;
for i:= to nodecount - do
begin
node := XMLDoc.DocumentElement.ChildNodes[i];
nodeList := node.ChildNodes;
for j := to nodeList.Count - do
begin
//fieldval:= nodeList[j].NodeName;
if nodeList[j].IsTextElement then
begin
fieldval := nodeList[j].NodeValue;
strdrg.Cells[j,i+]:=fieldval;
end;
end;
end;
end; 这个现实过程是我通过实践测试成功的 !基本方法全部给出只有你稍加改动就可以现实 !遇到错误不要放弃!
由于项目需要为包括c/s和b/s的多个平台提供统一业务逻辑,写个webservice来完成这个任务,通过webservice封装业务逻辑,为其他平台提供接口,以供调用,于是用delphi写一个webservice,起初没有任何采用任何编码,当然在调用的时候delphi客户端可以正常传输数据,c#网页部分调用却是乱码,肯定是两种语言的编码方式问题,引起的乱码,原因有了,最终也没有想到解决的办法。所以想两端提供一种统一的编码,通过编码和解码来达到编码方式的统一,这样应该就不会有乱码的问题了吧,我选择base64编码方式,base64在网络上良好的性能,这是满足这个所需要的,又折腾了一阵子,终于完成了,各个平台数据的统一,测试代码如下:
delphi 部分 :
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,EncdDecd;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
Edit3: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var s:AnsiString;
begin
s:=edit1.text;
edit2.Text:= EncodeString((s));
// 超越软件 http://www.cyhlw.com
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
edit3.Text:= DecodeString(edit2.text)
end;
end. c# 部分:
using System;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Text;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Response.ContentEncoding = System.Text.Encoding.GetEncoding( "GB2312" ); }
protected void Button1_Click(object sender, EventArgs e)
{ string str=""; localhost.IIHelloservice oserver = new localhost.IIHelloservice();
str=oserver.sayHello("超越软件 http://www.cyhlw.com");
//localhost.WebService1 oService = new localhost.WebService1();
//Label1.Text = oService.About();
this.TextBox1.Text = str;
byte[] bytes = System.Convert.FromBase64String(str);
str = "";
str = Encoding.Default.GetString(bytes);
TextBox2.Text = str;
//TextBox1.Text=Encoder.get
//byte[] bytes
//this.TextBox1.Text = Sys

Base64 三种语言间的加解密问题(delphi、C#、Java)

1. delphi 需要引用EncdDecd单元.

    oStream:= TStringStream.Create(sBase64Str);    try      oStream.Position := 0;      oMStream := TMemoryStream.Create;      try        EncdDecd.DecodeStream(oStream, oMStream);    //对二维码进行解base64, EncdDecd为delphi自带的base64单元        oMStream.Position := 0;        oMStream.SaveToFile('D:/base64Pic.jpg');     //保存二维码图片      finally        oMStream.Free;      end;    finally      oStream.Free;    end;

2. C# 调用代码

                    byte[] imgData = System.Convert.FromBase64String(sBase64Str); //解bas464字符串                    FileStream fs = new FileStream("D://OutPic.jpg", FileMode.CreateNew);                    fs.Write(imgData, 0, (int)imgData.Length);                    fs.Close();                    pictureBox1.Load("D://OutPic.jpg");

3. java  java的解决办法其实也很简单,把base64字符串的(大括号内的内容) {  }全部替换为空即可,即换行符,上代码:

		FileInputStream fis = new FileInputStream("d:/base64Img.txt");		int size = fis.available();		byte[] buffer = new byte[size];		fis.read(buffer, 0, size);		fis.close();		String tmp = new String(buffer);			tmp = tmp.replaceAll("
", "");		byte[] outData = Base64.decodeBase64(tmp);		FileOutputStream fos = new FileOutputStream("D:/aaa.jpg");			fos.write(outData, 0, outData.length);		fos.close();

在网上看到相关的资料,说的是java中加密生成base64串,delphi在解密base64时需要替换掉换行符,现在却反了过来,不知道是java改了还是delphi 改了。对了,delphi使用的版本为delphi XE1, C# 为 VS2010。

 
Delphi 读取 c# webservice XML的base64编码图片字符串转化图片并显示
上一篇:[BZOJ2125]最短路[圆方树]


下一篇:前端上传 base64 编码图片到七牛云存储