• 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。
     
  • 相关阅读:
    Codeforces Round #307 (Div. 2)E. GukiZ and GukiZiana
    bzoj2957: 楼房重建,分块
    分块入门。
    poj3690 Constellations
    Codeforces Round #451 (Div. 2)F. Restoring the Expression 字符串hash
    Codeforces Round #456 (Div. 2)D. Fishes
    Codeforces Round #450 (Div. 2)D. Unusual Sequences
    快速排序+分治法
    哈夫曼编码课程设计+最小优先对列建树。
    浅谈差分约束系统
  • 原文地址:https://www.cnblogs.com/chenmfly/p/4537350.html
Copyright © 2020-2023  润新知