欢迎您来到腾讯云!积分商城

腾讯云腾讯云论坛

 找回密码
 立即注册
忘了密码?

扫一扫,访问微社区

快捷导航
搜索
查看: 150889|回复: 2

[经验分享] 万象图片使用经验分享

[复制链接]

1

主题

0

好友

22

积分

小白[LV1]

Rank: 1

云币
112
威望
22
发表于 2015-8-5 16:52:54 |显示全部楼层 |未分类

最初选择万像图片是因为它的缩略图和其他图片处理的功能。不过刚开始的文档不是很容易理解而且版本更新后变化挺大,好在现在基本已经升级完善了。我就大致介绍下我当时遇到的困难和解决方案吧。

说下我的使用需求吧,公司项目中用到万象图片的地方:

①一个网站(Java开发)。

②三个手机App,IOS和android 都有。

③一个桌面客户端(C#开发)。


其中网站部分 直接使用SDK,而且签名可以直接通过SDK生成,无需再通过专门的服务接口生成,很简单不再介绍了。我主要说下App和桌面程序中使用腾讯云的方法。以下内容都是针对 手机App和桌面程序展开,而且由于我的项目只涉及了图片的上传功能,所以我也只是介绍下上传的功能,其他诸如复制删除查询等,也都是大同小异。

整体结构:

大致上就如下图所示了(自己的破本是纯娱乐用的,没装专业的作图工具,就用画图大致勾了下,将就看吧)

QQ截图20150805153129.png


客户端在需要上传图片的时候去更新签名,客户端向自己已经写好的签名生成接口发送请求,并取得签名结果。然后携带此签名调用腾讯云的上传接口上传图片。


有几点需要注意 :①如果是多次有效签名的话,只要签名没过期是可以不用更新,不过由于我的产品图片上传不是很频繁所以干脆每次都更新下。②自己的签名生成接口肯定是要有认证鉴权机制的,可以使你自己业务服务的鉴权策略,也可以是携带其他必要信息来做鉴权。③腾讯云的上传接口url中是包含了AppID和空间名称以及用户ID的,必须与你生成签名时候的信息保持一致,不然会返回签名不一致等各种错误的。


签名生成:

为了考虑安全性和灵活性。签名是万万不可在客户端(App和桌面客户端)生成的。所有必然要专门写一个用于生成签名的服务接口,供客户端调用获取签名使用。

不过,我的App和桌面客户端的业务服务 是用C# .net WebApi开发的一套RestFul 的服务接口。然而官方给出的SDK是没有提供.net版本的SDK的。没办法只能自己通过官方的生成方法一步一步自己搞定了。这里我就不得不吐槽下官方文档了:本来签名过程就很繁琐,像我这种没有官方SDK支持的开发者只能自己摸索。这倒也没什么,自己按照步骤一步一步搞,按照文档里的实例测试,只要把时间戳和随机数先固定成和文档里的一样,最终生成的签名和文档里的签名一样了也就说明搞定了。但。。是。。我无论如何测试结果都不正确。折腾了一上午,后来竟然发现,文档里的实例各步骤里的结果竟然没有任何关系。。。


好吧,吐槽结束,继续。可能也有一些朋友使用的是C# .Net开发,所以我就吧生成签名这部分代码整理了下发上来供大家参考下吧。

  1. private const string APPID = "your AppId";
  2.         private const string BUCKET = "your BUCKET";
  3.         private const string SECRETID = "SECRETID";
  4.         private const string SECRETKEY = "SECRETKEY";

  5.                 /// <summary>
  6.         /// 签名生成
  7.         /// </summary>
  8.         /// <param name="userId">自己项目的唯一的用户标识</param>
  9.         /// <returns></returns>
  10.         public static string Signature(string userId)
  11.         {
  12.                     string signStr_format = "a={0}&b={1}&k={2}&e={3}&t={4}&r={5}&u={6}&f=null";

  13.                     string expiredTime = CommonUtils.ConvertDateTimeInt(DateTime.Now.AddDays(3)).ToString();
  14.                     string currenTime = CommonUtils.GetTimeStamp().ToString();
  15.                     int ran = new Random().Next(10000000,99999999);
  16.                     string signStr = String.Format(signStr_format, APPID, BUCKET, SECRETID, expiredTime, currenTime, ran,userId);

  17.                     using (HMACSHA1 mac = new HMACSHA1(Encoding.Default.GetBytes(SECRETKEY)))
  18.                     {
  19.                         byte[] hash = mac.ComputeHash(Encoding.Default.GetBytes(signStr));
  20.                         byte[] signStr_byte = Encoding.Default.GetBytes(signStr);
  21.                         string sign = Convert.ToBase64String(copybyte(hash, signStr_byte));
  22.                         return sign;
  23.                     }
  24.         }

  25.                 public static byte[] copybyte(byte[] a, byte[] b)
  26.         {
  27.             byte[] c = new byte[a.Length + b.Length];
  28.             a.CopyTo(c, 0);
  29.             b.CopyTo(c, a.Length);
  30.             return c;
  31.         }
复制代码
CommonUtils.cs文件
  1. /// <summary>
  2.         /// 获取时间戳
  3.         /// </summary>
  4.         /// <returns></returns>
  5.         public static string GetTimeStamp()
  6.         {
  7.             TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
  8.             return Convert.ToInt64(ts.TotalSeconds).ToString();
  9.         }
  10.         /// <summary>
  11.         /// DateTime时间格式转换为Unix时间戳格式
  12.         /// </summary>
  13.         /// <param name="time"> DateTime时间格式</param>
  14.         /// <returns>Unix时间戳格式</returns>
  15.         public static int ConvertDateTimeInt(System.DateTime time)
  16.         {
  17.             System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
  18.             return (int)(time - startTime).TotalSeconds;
  19.         }
复制代码
图片上传:

签名获取到了,其实就剩下图片的上传了,上传还是很简单的即使不使用SDK,直接使用restful的API,应该也很容易可以看得懂的。而且像android 、 IOS、java 、php等都有sdk可以调用。我这里还是用C# 作为例子给大家说下,给那些使用restful Api的朋友一个简单的例子吧。

由于我的桌面程序要求很简单,只要传图片就好,而且对成功率也没有太大要求,所以我就用了最简单的http请求就搞定了。如果你需要获取上传进度等等。自己去写http请求的方法或找一些现成的工具库就可以了。


  1.         public static string HttpUploadFile(string url, string QcloudSign, string fileformname, string filepath)
  2.         {
  3.             
  4.             // 这个可以是改变的,也可以是下面这个固定的字符串
  5.             string boundary = "----acebdf13572468";

  6.             // 创建request对象
  7.             HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
  8.             webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
  9.             webrequest.Method = "POST";
  10.             webrequest.Headers.Add("Authorization: " + QcloudSign);
  11.             // 构造发送数据
  12.             StringBuilder sb = new StringBuilder();
  13.             // 文件域的数据
  14.             sb.Append("--" + boundary);
  15.             sb.Append("\r\n");
  16.             sb.Append("Content-Disposition: form-data; name=\"filecontent\";filename=\"" + fileformname + "\"");
  17.             sb.Append("\r\n");
  18.             sb.Append("Content-Type: ");
  19.             if (fileformname.EndsWith(".jpg"))
  20.                 sb.Append("image/jpeg");
  21.             else
  22.                 sb.Append("image/png");
  23.             sb.Append("\r\n\r\n");

  24.             string postHeader = sb.ToString();
  25.             byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);

  26.             //构造尾部数据
  27.             byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");

  28.             StringBuilder sb_m = new StringBuilder();

  29.             //sb_m.Append("<@INCLUDE *" + filepath + "*@>");
  30.             byte[] post_m = Encoding.UTF8.GetBytes(sb_m.ToString());

  31.             FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read);


  32.             //FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
  33.             long length = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length;
  34.             webrequest.ContentLength = length;
  35.             Stream requestStream = webrequest.GetRequestStream();

  36.             // 输入头部数据
  37.             requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

  38.             //requestStream.Write(post_m, 0, post_m.Length);


  39.             // 输入文件流数据
  40.             byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
  41.             int bytesRead = 0;
  42.             while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
  43.                 requestStream.Write(buffer, 0, bytesRead);


  44.             // 输入尾部数据
  45.             requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);

  46.             WebResponse responce = webrequest.GetResponse();
  47.             Stream s = responce.GetResponseStream();
  48.             StreamReader sr = new StreamReader(s);

  49.             string response_json= sr.ReadToEnd();
  50.             string imgurl = getUrl(<span style="font-size: 13.63636302948px; line-height: 19.0909080505371px;">response_json</span>);//从返回的json字符串中解析出图片url地址
  51.             return <span style="font-size: 13.63636302948px; line-height: 19.0909080505371px;">imgurl </span>;

  52.         }
复制代码
android和iOS端的上传都是调用的SDK的方法搞定,超级简单,没什么可说的。
其实只要大家之前用过其他的restful的Api,其实你就会发现,各个公司的服务接口都差不多,很容易理解和使用的。OK,就这样吧。

5

主题

0

好友

73

积分

小白[LV1]

Rank: 1

云币
298
威望
73
发表于 2015-12-21 22:00:08 |显示全部楼层
public static string HttpUploadFile(string url, string QcloudSign, string fileformname, string filepath)
最后一个filepath客服端怎么传入路径
回复

使用道具 举报

0

主题

0

好友

230

积分

小白[LV1]

Rank: 1

云币
550
威望
230
发表于 2017-10-21 10:56:04 |显示全部楼层
吐槽结束,继续。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册
您需要登录后才可以发帖 QQ登录

联系我们|腾讯云平台|积分商城|腾讯云官方论坛    

GMT+8, 2018-11-20 04:51 , Processed in 1.197167 second(s), 35 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部