AdWhirlでRotation (備忘録)

久しぶりにAdWhirlを経由した広告モデルのアプリを書いています。
以前のiRulerはLandscapeのみのUIでしたが今回のアプリではPortraitもサポートしてRotationを前提としています。
AdWhirlのAPIとしてはRotationした場合には下記のAPIを呼ぶ事になっています。


[AdWhirlView rotateToOrientation:(UIInterfaceOrientation)orientation]

iAdは全然大丈夫なのですが、その他の広告を表示しようとするとRotationが上手く行かない場合があります。

調べてみたのですが単純でした。
このメソッドは各ネットワークアダプタの同名のメソッドを呼ぶのですが、例えばAdMob用のネットワークアダプタはこのメソッドが実装されておらず、親クラスの何もしないメソッドが呼ばれていました。

ですので解決策としてはAdMob用のネットワークアダプタでメソッドをオーバラードしてやれば良いだけです。

AdWhirlAdapterGoogleAdMobAds.m

-(void)rotateToOrientation:(UIInterfaceOrientation)orientation {

    GADBannerView* adMobView;
    adMobView = (GADBannerView*)adNetworkView;

    switch (orientation) {
        case UIInterfaceOrientationPortrait:
        case UIInterfaceOrientationPortraitUpsideDown:
            adMobView.adSize = kGADAdSizeSmartBannerPortrait;
            break;
        case UIInterfaceOrientationLandscapeLeft:
        case UIInterfaceOrientationLandscapeRight:
            adMobView.adSize = kGADAdSizeSmartBannerLandscape;
            break;
        default:
            break;
    }
}

UIImageからOpenGLのテクスチャーを作る (備忘録)

OpenGL ESは非常に柔軟で強力なAPIを提供してくれています。
しかしその一方でOpen GL ESが非常に柔軟過ぎるが為にどこから取っ付いて良いか分からなくなってしまうのが、その移行への障害になっているように思います。

iOSではUIImageを始めとして非常に使い勝手の良い画像処理用のクラスが用意されています。しかしそれをOpenGLで使おうとすると画像フォーマットの変換やCPUとGPU間のメモリー転送等、考慮しなければいけない課題が多いように思います。

OpenGLで提供されている画像イメージはTextureの概念に拘束されます。従って、iOSで一般的に使用されているUIImageやCGImageとTextureの間の画像フォーマット変換とメモリーの転送の効率は非常に重要な問題になると思います。

調べているうちにiOS5からは便利なクラスが提供されていました。

GLKTextureLoader

このクラスを使用するとファイル上のイメージデータやUIImage(CGImageに変換した後)をかなり効率的にOpenGL ESのTextureに変換出来ます。

UIImage* uiImage;
CGImage* cgImage;
uiImage = [UIImage imageNamed:@"xxxx.png"];
cgImage = uiImage.CGImage;

NSMutableDictionary* dic;
NSError* error;

dic = [NSMutableDictionary alloc];
dic = [dic initWithCapacity:0];
[dic setObject:[NSNumber numberWithBool:YES] forKey:GLKTextureLoaderApplyPremultiplication];
[dic setObject:[NSNumber numberWithBool:NO] forKey:GLKTextureLoaderGenerateMipmaps];
[dic setObject:[NSNumber numberWithBool:NO] forKey:GLKTextureLoaderOriginBottomLeft];
[dic setObject:[NSNumber numberWithBool:NO] forKey:GLKTextureLoaderGrayscaleAsAlpha];

textureInfo = [GLKTextureLoader textureWithCGImage:cgImage options:dic error:&error];
[textureInfo retain];

他のビットマップイメージを直接アクセスしながら変換する方法と、パフォーマンスの違いがどの程度あるのかは、今のところ測定していませんが、Appleから直接提供されているAPIですのである程度は信頼出来るのではないかと思います。

最終的に取得される GLKTextureInfo の nameプロパティでTextureにアクセス出来ます。

計算カード

「さんすうの素 計算カード 1.3」 をリリースしました。

iPhone 5やiPod Touch(第5世代)の画面サイズに対応しました。

 

SketchCam 1.0

 SketchCam 1.0 をリリースしました。

 

だれでも簡単に水彩画のような写真が撮れます。
デバイスのアルバムに保存されたデータも変換出来ます。
もちろんTwitterやFacebookにも投稿出来ます。

 



 

 

Serial Shot Camera with Filter Effect 1.5.3

  Serial Shot Camera with Filter Effect 1.5.3 をリリースしました。

 

iOSデバイスのアルバムに保存されたデータにフィルタを掛けた時、Exifデータが欠落してしまう問題を修正しました。

SketchCam 1.0

 SketchCamをAppStroeにSubmit しました。

 現在 Waiting for Review です。

 

 

Serial Shot with Filter Effect 1.5

Serial Shot with Filter Effect 1.5 をAppStoreにアップロードしました。
最近はReviewまで時間が掛かっていますが、順次リリースされる予定です。

 

Serial Shot with Filter Effect 1.5 の主な新機能は以下の通りです。

・新しいフィルターの追加
iOS 5で13個、iOS 6で更に13個の合計26個のフィルターをサポートしています。

・画像サイズの選択
最高画質だけではなく、小さな画像サイズで撮影する事も出来ます。
小さな画像サイズを選択すれば、より高速に連写できます。
TwitterやFacebookに投稿する際にも小さいサイズの方が便利です。

Serial Shot with Filter Effect をリリースしました

Serial Shot with Filter Effectリリースしました。

高品質の画像で撮影できるカメラアプリです。
連続撮影が可能で、大切な “瞬間” を逃しません。
また多彩なフィルター(iOS5で12個、iOS6でさらに3個追加)を装備していますので、お好みの風合いに加工できます。

Build OpenCV for armv7s

現在のOpenCVは正式な環境では armv7s 対応のライブラリを作ってくれません。
そのため、アプリをビルドする場合にはプロジェクトから armv7s を外さなければなりません。
これからアプリを出そうという際には最新のアーキティクチャを使えないのはとうも納得が行きません。
そこでいろいろ調べてみました。
私はcmakeに関しては全くの素人で、これから知識を深めたいというわけでもありませんので、「とりあえずビルドできる」を目標にしています。

結論から言うと
opencv/ios/cmake/Toolchains/Toolchain-iPhoneOS_Xcode.cmake を編集してやります。

essage (STATUS “Setting up iPhoneOS toolchain”)
set (IPHONEOS TRUE)

# Standard settings
set (CMAKE_SYSTEM_NAME iOS)
# Include extra modules for the iOS platform files
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} “${CMAKE_CURRENT_SOURCE_DIR}/ios/cmake/Modules”)

# Force the compilers to gcc for iOS
include (CMakeForceCompiler)
CMAKE_FORCE_C_COMPILER (gcc gcc)
CMAKE_FORCE_CXX_COMPILER (g++ g++)

set (CMAKE_C_SIZEOF_DATA_PTR 4)
set (CMAKE_C_HAS_ISYSROOT 1)
set (CMAKE_C_COMPILER_ABI ELF)
set (CMAKE_CXX_SIZEOF_DATA_PTR 4)
set (CMAKE_CXX_HAS_ISYSROOT 1)
set (CMAKE_CXX_COMPILER_ABI ELF)

SET (CMAKE_OSX_ARCHITECTURES “armv7” “armv7s”)

# Skip the platform compiler checks for cross compiling
set (CMAKE_CXX_COMPILER_WORKS TRUE)
set (CMAKE_C_COMPILER_WORKS TRUE)

赤で色分けされた行を追加してやるだけです。
とりあえずテストプロジェクトでは iPhone 5用にビルドしても問題なく armv7s でコンパイルされており、リンカーでもエラーは出ません。

 

ただもう一つ問題が…

結論から言うと、armv7でもarmv7sでもパフォーマンスはあまり変わりませんでした(処理にも依存すると思うのですが)。

で、OpenCVをビルドした時のログを見てみると全くオプティマイズされていないようなのです。

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xct oolchain/usr/bin/clang -x c -arch armv7s -fmessage-length=0 -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototy pes -Wno-return-type -Wformat -Wno-missing-braces -Wparentheses -Wswitch – Wno-unused-function

 

これは多分armv7でビルドした際も同じだと思います。OpenCVのソース内までデバッガーで追って行くつもりは無いのでやはり “-Os” でコンパイルしたいです。
またOpenCVのcmakeと格闘です。
今回の事で少しだけcmakeも理解(?)出来た気もしますので時間のある時に試してみます。

Using OpenCV on iOS 6.0

OpenCVをビルドして、iOSで使用するまでのステップをまとめます。
環境は以下の通りです。

  • xcode 4.5.1 (iOS 6対応)
  • OpenCV 2.4.2
  • iPhone 5

1. OpenCVをダウンロードする
まずはOpenCVをダウンロードします。
これを書いている時点での最新バージョンは 2.4.2です。
OpenCV-2.4.2.tar.bz2
ファイルを解凍し、適当なディレクトリーにコピーして下さい。

2. OpenCVをビルドする
OpenCVのディレクトリ名を”opencv”に変更し、pythonのスクリプトを実行します。

$ mv OpenCV-2.4.2 opencv
$ python opencv/ios/build_framework.py ios

時間は少々かかりますが、先ほどのopencvディレクトリと同じ階層に”ios”というディレクトリが作成され、必要なものはそこにまとめられます。

3. xcodeでプロジェクトを作成
プロジェクトのタイプは何でも良いと思います。
作成したプロジェクトの $(PROJECT_NAME)-Prefix.pch を開き下記の部分を追加して下さい。

#import

#ifndef __IPHONE_3_0
#warning “This project uses features only available in iOS SDK 3.0 and later.”
#endif

#ifdef __cplusplus
#import <opencv2/opencv.hpp>
#endif

#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#endif

4. opencv.frameworkの追加
先ほどビルドしたiosディレクトリをプロジェクトのディレクトリにコピーし、
opencv.framework (ios/opencv.framework )ディレクトリをプロジェクトに追加します。ドラッグ&ドロップでOKです。

4. テストプログラムのビルド
とりあえずメインのViewControllerだけ新規作成します。Super Classは何でも構いません。一番簡単なUIViewControllerのサブクラスをひな形だけ作ります。
ファイルを作成したら、拡張子を”.mm”に変更します。こうする事でxcode標準(?)のObjective-CとC++を混在させる事が出来ます。
ちなみにiOS版のOpenCVはC++とで出来ています。

ロジックは何も書いていませんが、この状態でビルドが出来る事になります。
試しにビルドしてみると #include <ext/atomicity.h>  が見つからないとエラーが出ると思います。

不思議な事にエミュレータでビルドすると大丈夫なのですが、実機でビルドをするとエラーが出てきます。
正直な所、ここでかなりハマりました。
ext/atomicity.h なるヘッダファイルはxcodeのディレクトリの下に実際に存在します。またこのエラーはプリコンパイルヘッダを clung がC++用にコンパイルする時に出て来ます。

たどり着いたのはコンパイラの設定です。

問題があるのは “C++ Language Dialect” と “C++ Standard Library” のようです。

下記の様に設定し直します。

この状態でコンパイルは出来る様になったはずです。
しかしリンクに失敗する場合があります。「場合があると」というのは実機にiPhone 5を使用したときです。iPhone 5は新しい armv7s を搭載しています。xcode 4.5も armv7s 用のコードを出力します。しかし OpenCV がまだ armv7s に対応していないようで、Python のスクリプトでビルドしたライブラリには armv7s 用のコードが含まれていないようです。そのため実機用のコードも armv7 用のコードで統一しなければいけないようです。

これも設定で回避できます。

 

“Valid Architectures” からarmv7s を削除し、Build Archive Architecture Only を “NO” にします。

以上です。