SyntaxHighlighter

2011-02-20

gaeからpicasaに画像を登録する

WebGLでシェーダーの勉強をしていたら、ふと、canvas上のデータを画像として取り出すにはどうしたら良いのだろうと思いました。調べてみると、toDataURL()という関数を使用すると、DataURLという形式で得られるという事を知りました
toDataURL()で得られた値を、imgタグのsrcに設定すれば、そのまま画像が表示されて、右クリックなりで画像を保存を選択すれば、canvasで描写された画像をローカルに保存できるようです。
とすると、今度はこの画像をどこかイメージ保存サービスに楽に保存するにはどうしようかという事が気になってきましたので、ちょっとやってみました。(ちょっとと言っても、結構時間がかかりましたけど)

https://nekonekopic.appspot.com/
※今うまく動きません。。。

  • 動かなかったらすいません。特に認証部分が不思議動作するかも、です
  • アプリが信用できないなら、Picasa登録部分は使用しない方が良いです。画像表示までなら、ログインなしでも遊べます


google app engineとpicasa

とりあえずWebサーバをgaeとして、そこからpicasaに保存する、という方法にしました。

picasaに保存する理由は、gaeで画像データを持つと、あっという間に容量がいっぱいになりそうだったし、そもそもデータをずっと保存しておく自身なんて全くないです。最終データをpicasaに保存しておけば、いつでもこのアプリケーションを消すことができます(gaeのアプリって消せましたっけ??gaeアプリは消せます。。。)。なので多分必要以上に苦労してます。。。

蛇足ですが、アプリのイメージ図。


picasaとかgoogleサービスのAPIを利用するために、ライブラリが提供されているみたいです。これを使えば、生々しくテキストデータを扱わずに済むようです。
このライブラリを使ってpicasaのAPIを使うチュートリアルがあるので、これを参考にして、アルバムやイメージの登録など、基本的に動作できました。

厄介なのが、picasaへの認証方法でした。AuthSubを使いましたが、この部分が動くようになるまでが一番時間がかかったような気がします。。。正しいTokenじゃないとか、Tokenのスコープが違うと何度も怒られたり。。。

AuthSubを頑張っている部分。これが本当に良いのか全く想像がつきません。。。。

def getClient(uri):
user = users.get_current_user()
if user:
gd_client = gdata.photos.service.PhotosService(email=user.email())
# workaround http://code.google.com/p/gdata-python-client/issues/detail?id=184
else:
gd_client = gdata.photos.service.PhotosService()

gdata.alt.appengine.run_on_appengine(gd_client)

session_token = None
authsub_token = gdata.auth.extract_auth_sub_token_from_url(uri)
if authsub_token:
session_token = gd_client.upgrade_to_session_token(authsub_token)
logging.info("session_token=%s" % (session_token))
if session_token and user:
gd_client.token_store.remove_all_tokens()
gd_client.token_store.add_token(session_token)
logging.info("Already login")
elif session_token:
gd_client.current_token = session_token
logging.info("Not Login")

logging.info("AuthSubToken=%s", gd_client.GetAuthSubToken())
if gd_client.GetAuthSubToken():
return gd_client
else:
return None


画像アップロード

ブラウザからは、画像がdataURL形式と呼ばれる、テキストデータで送られてくるので、バイナリに変換する必要があります(多分・・・)。画像本体部分は、Base64エンコードされているようなので、以下の通りに解析しました。全パターン対応していないみたいですけど。


def convertDataURL(self, url):
m = re.match(r'data:(.*);base64,(.*)', url)
if m:
imagedata = {'type':m.group(1), 'data':base64.b64decode(m.group(2))}
return imagedata
return None


Picasaへの画像アップロードはこんな感じ。

def insertPhoto(self, client, albumid, title, image, image_type):
try:
albumurl = "/data/feed/api/user/default/albumid/%s" % (albumid)
photo = client.InsertPhotoSimple(albumurl, albumurl, title, StringIO(image), image_type)
return photo
except  gdata.photos.service.GooglePhotosException:
logging.info(traceback.format_exc())
self.redirect(PicasaAuth.originalURL)


Picasaへの画像登録方法は、このサイトも参考になりました。


セッション中の画像の渡し方

意外に悩んだのがこれ。いくつかページ遷移する間にどうやって画像を渡していこうかと悩んで、必要になるまでサーバ側に画像を送りたくないなあとか、cookieでセッションとか難しいなあ、memcacheオプション使った方が良いのかなあ、等等考えて、結局、一番後腐れが無いだろうという事で、sessionStorageを使う事にしました。画像がdataURLというテキスト形式になっている事も好都合!

コード自体は、練習問題レベルで、
画像を登録

function uploadToAlbum(canvas, url) {
if (!sessionStorage) {
alert("No SessionStorage");
return;
} else {
sessionStorage.setItem("photo", canvas.toDataURL());
window.open(url, null);
}
}


画像をhiddenパラメータに設定、またはimgタグに設定

function setPhoto() {
var input = document.getElementById("photo");
input.value = sessionStorage.getItem("photo");

var img = document.getElementById("capture");
img.src = sessionStorage.getItem("photo");

}


今回思った事。
  • ここまで書いておいてなんですが、このアプリオリジナルって訳ではなくて、似たような事をしているアプリケーションをつい最近、developer summitのHTML5グループの展示でありました。。。
  • 実はPicasaに直接アクセスできるjavascriptがあります、って話になると、この苦労はなんだろうって気になります。
  • 認証系は、場当たり的にやったので怖いです。ちゃんと勉強してからつかいませう。へたにライブラリがあると、よく分からなくても使えてしまうので、危険だなあ・・・
  • 相当我流なので、これが正しいアプリケーションの作り方なのかさっぱり分かりません。ちゃんと勉強しましょう
  • そろそろ3次元も勉強・・・

2 件のコメント:

  1. GAEアプリは確か削除できたかと思います。ただ復旧は無理だったかと。

    返信削除
  2. >oratoanさま
    ご指摘ありがとうございます。GAEアプリ消せるようですね(http://blog.livedoor.jp/chuhei1107/archives/51263303.html)。調査不足でした、ありがとうございます。

    返信削除

Related Posts Plugin for WordPress, Blogger...