星期二, 10月 02, 2012

Picasa with C#

最近有個專案,有需要把圖片分享給他人,沒有很多的 resource,所以需要找一個免費又可以依賴的 service,噹噹噹..所以找到 google 的 Picasa 這個東東,在這裡做個筆記,讓大家以後有需要用到這服務的朋友,可以不用再花很多時間去尋找..

先把 picasa 限制說出來,有需要的評估一下:

1.相片大小上限:圖片一律不能超過 20 MB 及 5000 萬像素。
2.影片大小上限:上載的單一影片大小一律不能超過 1GB。
3.網路相簿數量上限:10,000本
4.每本網路相簿的相片和影片數量上限:1,000張
5.總儲存空間:「Picasa 網路相簿」可儲存 1 GB 的相片和影片。
6.免費儲存空間限制:只要相片大小低於 800x 800 像素,影片長度少於 15 分鐘,就不會計入免費儲存空間配額。
7.如果加入 Google+ 將獲得更多免費儲存空間:系統會將您上載至 Google+ 的相片自動調整成 2048 像素大小,並免費儲存這些相片。如同「Picasa 網路相簿」,您可以免費上載的長度 15 分鐘以內的影片。

http://support.google.com/picasa/bin/answer.py?hl=zh-Hant&answer=43879
http://support.google.com/picasa/bin/answer.py?hl=zh-Hant&answer=1321133
http://support.google.com/picasa/bin/answer.py?hl=en&answer=1224181

優點是:

1.如果照片在 800 * 800 像素以下,我們有 10000000(10,000x1,000) 張照片可以使用,這樣對一般使用者來說幾乎就沒有空間限制
2.可以照片直接外連
3.Picasa 裡面的 folder 限制瀏覽但是檔案可以外連
4.google 牌子夠大,不怕倒(不過基本備份還是自己要有)

缺點是:

1.流量限制,我在官方的 api 裡面,並沒有找到很明確的說明,不過以網路上的一些說法是,流量太大就把你擋起來(這這這..來陰的)

看了上列的優點和缺點以後,要不要使用這個服務,心理就有個底了,不過 Bibby 我是覺得 Google Picasa 是可以用用看,所以就參考了一下 Google API,搜尋一下 C# 要如何使用這個免費的服務,準備用 C# 來把它寫起來..

開 nuget ,直接載下列這三個 reference,這樣就可以使用了..

Google.GData.Photos
Google.Picasa
Google.GData.Client

不過如果您載下來就會用,Bibby 跟您拜一下了,因為真的不知道如何下手XD..所以又在網路上找了一堆有的沒有的資料,終於裡出了一點頭緒,整理一下常用的功能如:"新增相簿" "刪除相簿" "上傳照片" "刪除照片" "下載照片" 等這些功能,給大家參考參考(吃齋念佛做好事說好話佛心來著低^^)

public class GooglePicasaUtilities
{
PicasaService myPicasa;
string serviceName = "Test-1.0";

string _TargetAccount;
public string TargetAccount
{
get
{
if (string.IsNullOrEmpty(_TargetAccount))
throw new Exception("Please enter the target account.");
return _TargetAccount;
}
set
{
_TargetAccount = value;
}
}

public GooglePicasaUtilities(string username, string password)
{
myPicasa = new PicasaService(serviceName);
myPicasa.setUserCredentials(username, password);
}

public GooglePicasaUtilities(string username, string password,
string targetAccount)
: this(username, password)
{
TargetAccount = targetAccount;
}

//download photo
public void DownloadPhoto(string albumName, string photoTitle,
string saveFolder, ImageFormat imageFormat)
{
PicasaFeed myPicasaFeed = GetPicasaFeed(albumName);
var item = myPicasaFeed.Entries
.Where(a => a.Title.Text == photoTitle)
.FirstOrDefault();
if (item != null)
{
Stream mystream = myPicasa.Query(new Uri(item.Content.Src.ToString()));
Bitmap m = new Bitmap(mystream);
string path = string.Format("{0}.{1}",
Path.Combine(saveFolder, item.Title.Text),
imageFormat.ToString().ToLower());
m.Save(path, imageFormat);
}
}

//delete photo
public void DeletePhoto(string albumName, string photoTitle)
{
PicasaFeed myPicasaFeed = GetPicasaFeed(albumName);
var item = myPicasaFeed.Entries
.Where(a => a.Title.Text == photoTitle)
.FirstOrDefault();
if (item != null)
{
item.Delete();
}
}

//delete album
public void DeleteAlbum(string albumName)
{
AlbumQuery myAlbumQuery =
new AlbumQuery(PicasaQuery.CreatePicasaUri(TargetAccount));
PicasaFeed myPicasaFeed = myPicasa.Query(myAlbumQuery);

var album = myPicasaFeed.Entries
.FirstOrDefault(a => a.Title.Text == albumName);
if (album != null)
album.Delete();
}

//get photo info list
public List<PicasaPhotoInfo> GetPhotoInfoList(string albumName)
{
PicasaFeed myPicasaFeed = GetPicasaFeed(albumName);
//List<Google.GData.Photos.PicasaEntry> data=new List<Google.GData.Photos.PicasaEntry>();
var data = new List<PicasaPhotoInfo>();
foreach (PicasaEntry p in myPicasaFeed.Entries)
{
data.Add(new PicasaPhotoInfo()
{
Id = p.Exif.ImageUniqueID.Value,
Title = p.Title.Text,
Summary = p.Summary.Text,
Url = GetRealUrl(p.Media.Content.Url)
});
}
return data;
}

//Upload a image.
public void UploadImage(string albumName, byte[] imageByteArr,
string photoTitle)
{
string albumId = GetAlbumId(albumName);
Uri newURI = new Uri(PicasaQuery.CreatePicasaUri(TargetAccount, albumId));
using (Stream imageStream = new MemoryStream(imageByteArr))
{
myPicasa.Insert(newURI, imageStream, "image/jpeg", photoTitle);
}
}

//create new album
public void InsertNewAlbum(string title, string summary)
{
AlbumQuery myAlbumQuery =
new AlbumQuery(PicasaQuery.CreatePicasaUri(TargetAccount));
PicasaFeed myPicasaFeed = myPicasa.Query(myAlbumQuery);

Album newAlbum = new Album();
newAlbum.Title = title;
newAlbum.Summary = summary;
myPicasa.Insert(myPicasaFeed, newAlbum.PicasaEntry);
}

//Get album info list
public List<PicasaAblumInfo> GetAlbumInfoList()
{
AlbumQuery myAlbumQuery =
new AlbumQuery(PicasaQuery.CreatePicasaUri(TargetAccount));
PicasaFeed myPicasaFeed = myPicasa.Query(myAlbumQuery);

var rtn = new List<PicasaAblumInfo>();
foreach (PicasaEntry p in myPicasaFeed.Entries)
{
Album myAlbum = new Album();
myAlbum.AtomEntry = p;

rtn.Add(new PicasaAblumInfo()
{
Id = myAlbum.Id,
Title = myAlbum.Title,
Summary = myAlbum.Summary
});
}
return rtn;
}

Dictionary<string, string> albumIdDicTemp = new Dictionary<string, string>();
private string GetAlbumId(string albumName)
{
if (albumIdDicTemp.ContainsKey(albumName))
return albumIdDicTemp[albumName];

var infoList = GetAlbumInfoList();
albumIdDicTemp= infoList.ToDictionary(a=>a.Title,b=>b.Id);
if(albumIdDicTemp.ContainsKey(albumName))
return albumIdDicTemp[albumName];
return "";
}

Dictionary<string, PicasaFeed> PicasaFeedDicTemp =
new Dictionary<string, PicasaFeed>();
private PicasaFeed GetPicasaFeed(string albumName)
{
if (PicasaFeedDicTemp.ContainsKey(albumName))
return PicasaFeedDicTemp[albumName];

string albumId = GetAlbumId(albumName);
PhotoQuery myPhotoQuery =
new PhotoQuery(PicasaQuery.CreatePicasaUri(TargetAccount, albumId));
var pf = myPicasa.Query(myPhotoQuery);
PicasaFeedDicTemp[albumName] = pf;
return pf;
}

private string GetRealUrl(string url)
{
var arr = url.Replace("https://", "").Split('/').ToList();
arr.Insert(arr.Count() - 1, "s1600");
return string.Concat("https://" + string.Join("/", arr.ToArray()));
}
}

public class PicasaPhotoInfo
{
public string Id { get; set; }
public string Title { get; set; }
public string Url { get; set; }
public string Summary { get; set; }
}

public class PicasaAblumInfo
{
public string Id { get; set; }
public string Title { get; set; }
public string Summary { get; set; }
}


使用方式


var picasa = new GooglePicasaUtilities(targetAcccount, targetPassword,targetAcccount);

//---about album---
//create Album
picasa.InsertNewAlbum(targetAlbumName,"summary");

//delete album
picasa.DeleteAlbum(targetAlbumName);

//get album info
picasa.GetAlbumInfoList();

//get photo list by albumName
picasa.GetPhotoInfoList(targetAlbumName);

//---about photo
//download photo
picasa.DownloadPhoto(targetAlbumName,photoTitle,saveFolder,ImageFormat.Bmp);

//delete photo
picasa.DeletePhoto(targetAlbumName,photoTitle);

//upload image
using(FileStream ms=File.OpenRead(filePath))
{
//bmap.Save(ms, ImageFormat.Jpeg);
byte[] bytes = new byte[ms.Length];
ms.Read(bytes, 0, bytes.Length);
ms.Seek(0, SeekOrigin.Begin);
picasa.UploadImage(targetAlbumName,bytes,photoTitle);
}


大概就這樣了,有需要的就拿去用吧!有 bug 記得別找我^^
有問題再一起討論吧..

參考
http://playpcesor.blogspot.com/2011/06/google-android-app-picasa.html
http://abintech.twidv.com/2009/02/blogger-picasa.html

2 則留言:

Vito 提到...

版大您好

有個問題想請教一下版大
我也是用大至這樣的方法在處理picasa相簿
不過, 在捉取相簿清單時, 我一直無法取得權限設定成"僅限知道連結的使用者"的相簿
不知道版大有沒有這方面的資訊

謝謝

Bibby 提到...

我一直是抓我自己傳的,所以對於權限這部份,沒太大的研究,不好意思^^||