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

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



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



的方法:

1.c#的webservice现实见

 http://www.greensoftcode.net/techntxt/20127118441582992373 之前的文章。

2.在客户端用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,   0,   byt.Length) ;

          ms.Seek(0,   System.IO.SeekOrigin.Begin) ;

   len=ms.Length;

           pictureBox1.Image   =   Image.FromStream(ms) ;



  }

  图片显示没有问题!这就证明啦asp.net webservice 以XML字符串显示图片没有问题 ,只要delphi的



算法正确就可以。

3.下面用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:=0;

  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函数

 

1.web端函数为:

              [WebMethod] 

  public string gettable(int  pageIndex , int pageSize , out int  recordCount, out int pageCount ,string keyword)

  {

                  recordCount=0;

   pageCount=0;

   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();



  }

2.客户端

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:=0   to    strdrg.rowcount-1   do

      for   j:=0   to   strdrg.colcount-1   do 

         strdrg.Cells[j,i]:= '';

    strdrg.Cells[0,0]:='编号';

    strdrg.Cells[1,0]:='类型';

    strdrg.Cells[2,0]:='状态';

     strdrg.Cells[3,0]:='工号';

    strdrg.Cells[4,0]:='姓名';

    strdrg.Cells[5,0]:='电话';

    strdrg.Cells[6,0]:='所收';

    strdrg.Cells[7,0]:='姓名';

    strdrg.Cells[8,0]:='电话';

    strdrg.Cells[9,0]:='姓名';

    strdrg.Cells[10,0]:='电话';

    strdrg.Cells[11,0]:='所属';

    strdrg.Cells[12,0]:='日期';

     strdrg.ColWidths[0]:=100;

     strdrg.ColWidths[1]:=56;

     strdrg.ColWidths[2]:=62;

     strdrg.ColWidths[3]:=70;

     strdrg.ColWidths[4]:=65;

     strdrg.ColWidths[5]:=100;

     strdrg.ColWidths[6]:=120;

     strdrg.ColWidths[7]:=120;

     strdrg.ColWidths[8]:=120;

     strdrg.ColWidths[9]:=80;

     strdrg.ColWidths[10]:=80;

     strdrg.ColWidths[11]:=120;

     strdrg.ColWidths[12]:=120;

  XMLDoc:=TXMLDocument.Create(Application);

  XMLDoc.XML.Text:=xmlstr;

   XMLDoc.Active:=true;

  nodecount:=XMLDoc.DocumentElement.ChildNodes.Count;

  for i:=0 to nodecount -1 do

  begin

  node := XMLDoc.DocumentElement.ChildNodes[i];

  nodeList := node.ChildNodes;

  for j := 0 to nodeList.Count - 1 do

   begin

    //fieldval:= nodeList[j].NodeName;

    if nodeList[j].IsTextElement then

      begin

        fieldval := nodeList[j].NodeValue;

        strdrg.Cells[j,i+1]:=fieldval;

      end;

   end;

  end;

 end;



这个现实过程是我通过实践测试成功的 !基本方法全部给出只有你稍加改动就可以现实 !遇到错误不要放弃!
由于项目需要为包括c/s和b/s的多个平台提供统一业务逻辑,写个webservice来完成这个任务,通过webservice封装业务逻辑,为其他平台提供接口,以供调用,于是用delphi写一个webservice,起初没有任何采用任何编码,当然在调用的时候delphi客户端可以正常传输数据,c#网页部分调用却是乱码,肯定是两种语言的编码方式问题,引起的乱码,原因有了,最终也没有想到解决的办法。所以想两端提供一种统一的编码,通过编码和解码来达到编码方式的统一,这样应该就不会有乱码的问题了吧,我选择base64编码方式,base64在网络上良好的性能,这是满足这个所需要的,又折腾了一阵子,终于完成了,各个平台数据的统一,测试代码如下:

1 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.

 

2  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。
 

你可能感兴趣的:(webservice)