zoukankan      html  css  js  c++  java
  • 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。
     
  • 相关阅读:
    【PAT甲级】1043 Is It a Binary Search Tree (25 分)(判断是否为BST的先序遍历并输出后序遍历)
    Educational Codeforces Round 73 (Rated for Div. 2)F(线段树,扫描线)
    【PAT甲级】1042 Shuffling Machine (20 分)
    【PAT甲级】1041 Be Unique (20 分)(多重集)
    【PAT甲级】1040 Longest Symmetric String (25 分)(cin.getline(s,1007))
    【PAT甲级】1039 Course List for Student (25 分)(vector嵌套于map,段错误原因未知)
    Codeforces Round #588 (Div. 2)E(DFS,思维,__gcd,树)
    2017-3-9 SQL server 数据库
    2017-3-8 学生信息展示习题
    2017-3-5 C#基础 函数--递归
  • 原文地址:https://www.cnblogs.com/chenmfly/p/4537350.html
Copyright © 2011-2022 走看看