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。
 
posted on 2015-05-28 23:35  雪夜  阅读(2150)  评论(0编辑  收藏  举报