メモ。
iPhoneアプリのバンドルに同梱したPNGファイルは、ビルド時に最適化処理が行われてしまうため、そのままではlibpngで読み込むことが出来ません。iPhone向けに最適化されたPNGをlibpngで扱う方法は、いまのところ二つ。
1:最初から最適化をしないようにする
参考にしたページはこちら。
http://d.hatena.ne.jp/wasabi-arts/20090301/1235856525
このように、IPHONE_OPTIMIZE_OPTIONS=-skip-PNGsを追加するか、
またはこのように、最初っから圧縮をしないように設定する。
2:最適化したファイルをいったんUIImageで読み出して、再度PNGでファイル書きだしする
いったんUIImageを使って当該ファイルをロードして、ファイルにpng形式で書き出せばよいらしいです。
(@nakamura001さんありがとうございます!)
[2009/10/24 22:20追記]
@nakamura001さんがご自身のブログで検証結果をアップされてます。
http://d.hatena.ne.jp/nakamura001/20091024/1256371800
UIButtonからPNG画像を抜く方法ですが、これを応用すればUIButtonに最適化されたPNGを使用していても普通のPNG画像を取得することが出来ます。私の環境でもテストしたところ、うまくいきました!
2009年10月23日金曜日
2009年10月17日土曜日
PythonのEvernote APIをProxyに対応させることに成功しました
前回記事で見事大失敗したので、今回改めてThriftのTHttpClientのPython実装にProxy機能を持たせるチャレンジを行いました。結果、無事成功しました!さっそく共有させていただきたいと思います。
■PythonのEvernote APIをProxyに対応させる方法
まずはEvernote APIの中で使用されている通信クラス、thrift.transport.THttpClientを修正する必要があります。
以下のようにTHttpClient.pyを修正してください(または別名ファイルとして保存してください)。
http://gist.github.com/204501
修正しましたら、APIを呼びだす側のコードを以下のように変更してください。
■何をやっているか
そもそもThriftのTHttpClientはプロキシを使うこと自体が全く想定されていない?作りになってまして、他の言語の実装でもすべてプロキシは使えるようになっていません。たとえばC#での実装はこちら(http://issues.apache.org/jira/secure/attachment/12391517/THttpClient.cs)ですが、これもプロキシは使えません。
というわけで、勝手に自分でTHttpClientを再実装してプロキシを使えるようにしています。あんまりよい方法ではないと思いますので、本番サーバーなどでは真似しないでください><
■前回からの改良点
前回はhttplib.HTTPを使うのを辞めて、httplib.HTTPConnectionクラスを使うようにしたのですが、コレがそもそもの大失敗でした。といいますか、httplib.HTTPのソースを見たら内部でばっちりhttplib.HTTPConnectionが使われてるじゃないですかorz
これらを踏まえて、今回はTHttpClientの中でhttplib.HTTPをそのまま使うようにして解決しました。
他にもhttplib.HTTPResponseは以下のようにしてファイルポインタが取得できるとか
■PythonのEvernote APIをProxyに対応させる方法
まずはEvernote APIの中で使用されている通信クラス、thrift.transport.THttpClientを修正する必要があります。
以下のようにTHttpClient.pyを修正してください(または別名ファイルとして保存してください)。
http://gist.github.com/204501
修正しましたら、APIを呼びだす側のコードを以下のように変更してください。
# これを・・・ # import thrift.transport.THttpClient as THttpClient # こうする import thrift.transport.MyTHttpClient as THttpClient import evernote.edam.userstore.UserStore as UserStore import evernote.edam.userstore.constants as UserStoreConstants import evernote.edam.notestore.NoteStore as NoteStore import evernote.edam.type.ttypes as Types ########## # 中略 ########## # プロキシを使わなくて良いときはproxy引数を無視すればよい # userStoreHttpClient = THttpClient.THttpClient(userStoreUri) # プロキシを使いたいときはこうする userStoreHttpClient = THttpClient.THttpClient(userStoreUri, proxy="myproxy.example.com:8080") userStoreProtocol = TBinaryProtocol.TBinaryProtocol(userStoreHttpClient) userStore = UserStore.Client(userStoreProtocol) versionOK = userStore.checkVersion(applicationClientNameString, UserStoreConstants.EDAM_VERSION_MAJOR, UserStoreConstants.EDAM_VERSION_MINOR)これだけで通信時にプロキシを介してくれるようになりました!
■何をやっているか
そもそもThriftのTHttpClientはプロキシを使うこと自体が全く想定されていない?作りになってまして、他の言語の実装でもすべてプロキシは使えるようになっていません。たとえばC#での実装はこちら(http://issues.apache.org/jira/secure/attachment/12391517/THttpClient.cs)ですが、これもプロキシは使えません。
connection.Proxy = null;
ってなってます。というわけで、勝手に自分でTHttpClientを再実装してプロキシを使えるようにしています。あんまりよい方法ではないと思いますので、本番サーバーなどでは真似しないでください><
■前回からの改良点
前回はhttplib.HTTPを使うのを辞めて、httplib.HTTPConnectionクラスを使うようにしたのですが、コレがそもそもの大失敗でした。といいますか、httplib.HTTPのソースを見たら内部でばっちりhttplib.HTTPConnectionが使われてるじゃないですかorz
self.__http = httplib.HTTP(self.host, self.port) self.__http._conn #これでhttplib.HTTPConnectionが取得できるそして前回最大の失敗がread()メソッドが呼ばれるたびに接続をcloseしてしまっていたところです。httplib.HTTPの実装をみてようやく気づいたのですが、ここでは接続をCloseしてはいけないんですね・・・
これらを踏まえて、今回はTHttpClientの中でhttplib.HTTPをそのまま使うようにして解決しました。
他にもhttplib.HTTPResponseは以下のようにしてファイルポインタが取得できるとか
response = conn.getresponse() response.fp # これがファイルポインタ。httplib.HTTP.read()でも使われているhttplibはとにかくドキュメントに書いてない仕様が多すぎです><
2009年10月11日日曜日
UIViewControllerのtouchesBeganとかtouchesEndedが上手く機能しなかったと思ったら・・・
ひさっびさに普通のUIKitを使ったiPhoneアプリを作ったりし始めたらかなりの範囲を忘れてしまっていて大ハマりしてます。中でも一番困ったのがこれ。
こういうときに考えられる原因は、だいたいがInterface BuilderでInteraction Enabledのチェックを入れ忘れているとか、ViewControllerとViewをつなぎ忘れているとかそんなのばっかりなので真っ先に調べてみました。が、やはり問題は見つかりません。
試しにUIViewControllerではなくUIViewにtouchesBeganを載せてみるとコレが動くんです。ああ、OS 3.1.2ぐらいから挙動が変わったのかなとか思っていたら、
http://stackoverflow.com/questions/1025574/uiviewcontroller-not-receiving-touchesbegan-message
retainしたら解決しました。ほんと腕がなまってる・・・
@implementation AbesiViewControllerとまぁ、なんの変哲もないUIViewControllerにタッチを扱うためのイベントハンドラを搭載してみただけなのですが、コレがまぁ動かない動かない!
- (void)viewDidLoad
{
[super viewDidLoad];
self.wantsFullScreenLayout = YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)dealloc
{
[super dealloc];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// なぜか出力されない
NSLog(@"touchesBegan");
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// なぜか出力されない
NSLog(@"touchesMoved");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// なぜか出力されない
NSLog(@"touchesEnded");
}
@end
こういうときに考えられる原因は、だいたいがInterface BuilderでInteraction Enabledのチェックを入れ忘れているとか、ViewControllerとViewをつなぎ忘れているとかそんなのばっかりなので真っ先に調べてみました。が、やはり問題は見つかりません。
試しにUIViewControllerではなくUIViewにtouchesBeganを載せてみるとコレが動くんです。ああ、OS 3.1.2ぐらいから挙動が変わったのかなとか思っていたら、
http://stackoverflow.com/questions/1025574/uiviewcontroller-not-receiving-touchesbegan-message
OK, I'm a dummy. It works fine. The problem was, I didn't realize I was sending a release message to the UIViewController without having retained it elsewhere first. So that was causing the problem.あーーー!そうだ!!!UIViewControllerをretainしてない!!!orz
retainしたら解決しました。ほんと腕がなまってる・・・
登録:
投稿 (Atom)