Hatena::ブログ(Diary)

まさとしの自習帳 このページをアンテナに追加 RSSフィード

2011-10-18

UIButtonの背景色を簡単設定

UIButtonの背景色を変えるのに、一々画像作るの面倒だな〜と思ってたら、UIButtonに背景色を設定する | 404 odakoh Not Foundで、「プログラム内で画像作っちゃおう」って感じでやっていたので、自分用にアレンジしてみました。

元ネタ
・UIColor指定で背景色画像作成

変更点
・カテゴリ使ってUIButtonを拡張
色指定を@"RRGGBB"にしたIFを追加

で、以下がその実装です。

//  UIButton+BGColor.h
@interface UIButton (BGColor)

- (void)setBackgroundColor:(UIColor *)color forState:(UIControlState)state;
- (void)setBackgroundColorString:(NSString *)colorStr forState:(UIControlState)state;

@end
//  UIButton+BGColor.m
#import "UIButton+BGColor.h"

#import <QuartzCore/QuartzCore.h>
#import "UIColor-Expanded.h"

@implementation UIButton (BGColor)

- (void)setBackgroundColor:(UIColor *)color forState:(UIControlState)state {
    CGRect buttonSize = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    UIView *bgView = [[[UIView alloc] initWithFrame:buttonSize] autorelease];
    bgView.layer.cornerRadius = 5;
    bgView.clipsToBounds = true;
    bgView.backgroundColor = color;
    UIGraphicsBeginImageContext(self.frame.size);
    [bgView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [self setBackgroundImage:screenImage forState:state];
}

- (void)setBackgroundColorString:(NSString *)colorStr forState:(UIControlState)state {
    UIColor *color = [UIColor colorWithHexString:colorStr];
    [self setBackgroundColor:color forState:state];
}

@end

2つ目のメソッドが見ての通り文字列での背景色指定ですが、これいらない方は、UIColor-Expanded.hが不要です。というか、UIColor-Expanded.h取ってくるの面倒な方は省くと良いですね。
UIColor-Expanded.hによるUIColorの拡張については、以前の記事をどうぞ。もの自体はこちらで公開されています。

そして、使い方。

[button1 setBackgroundColor:[UIColor blueColor] forState:UIControlStateNormal];
[button2 setBackgroundColorString:@"ff0000" forState:UIControlStateNormal];

結果は(見なくても分かると思うけど)こんな感じになります。
f:id:masatoshisw20:20111019060110p:image

2011-08-08

ネタアプリと広告収入(iAd/AdMobその後)

ネタアプリ作って無料でリリースしたけど、なんとなくもったいないんで広告収入の雰囲気つかむのも兼ねてiAd付けて実験してみるか、って以前やったやつが、多少数字も大きくなって、まぁ参考くらいにはなるかなって思ったので、このあたりでまとめてみます。
あと、4/29のv1.2からAdMobもやってみた。

iAd全期間(2011/2/5〜2011/8/8)
f:id:masatoshisw20:20110809060914p:image

  • Fill Rateは平均なので低くなっていますが、最近はもっと高いです。iAd直近10日間を参照。

iAd国別全期間(2011/2/5〜2011/8/8)
f:id:masatoshisw20:20110809060913p:image

  • 日本まだ〜?

iAd直近10日間(2011/7/30〜2011/8/8)
f:id:masatoshisw20:20110809060911p:image

  • 常用するアプリじゃないので、起動率が低いの丸分かり(;_;)

AdMob全期間(2011/4/29〜2011/8/8)
f:id:masatoshisw20:20110809060915p:image

  • Fill Rateは高いが、想像以上に低かったePCM(T_T)


  • ありきたりの結論
    • iAdだけだとFill Rate低くて取りこぼしがあるので、AdMobか何かも併用しましょう。
    • 広告で勝負するなら、起動回数が増えるアプリにしましょう。

2011-07-16

簡単に電光掲示板を作ってみる

『[福井]iPhoneアプリ開発勉強会』(http://atnd.org/events/16933)で話して来ました。

内容は、簡単な画像処理としてUIImageのビットマップをさわってモノクロ画像にするやり方の紹介と、簡単な電光掲示板の作成について。正直、電光掲示板の一般的な作り方とか知らないけど、まぁ、こうすればそれっぽくできますよ、という感じ。

簡単な画像処理(モノクロ画像化)はこちらの記事を参照。
【コラム】実践! iPhoneアプリ開発 (4) カメラアプリの作り方 (4) - 写真にエフェクトをかける | エンタープライズ | マイコミジャーナル
注意点としては、RGB値を参照するbitに注意すること。変な色になるなら調整しましょう。

で、ここからが本題です。

簡単な電光掲示板の仕様は次のとおり。

  • 横(480x320)レイアウトで、LEDの配置は30x20
  • 1LEDあたり、LEDのサイズは12pixelでマージンが2pixel
  • 16pixelずつメッセージ画像はスクロールする
  • メッセージ画像の上に、スクロールしないマスク画像を重ねる

メッセージ画像をUILabelで作って何も画像処理しないとこうなります。

f:id:masatoshisw20:20110716094013p:image:w360

見てのとおり、LEDの一部だけ色が付いてるのが気持ち悪いので、ここで画像処理を投入し、点灯するか消えるかはっきりさせます。

  1. UILabelからUIImageを作る
  2. 作ったUIImageを加工して、LEDの中心の色をLED全体の色にする

UILabelをtargetViewに与えるとUIImageができる

+ (UIImage *)createImage:(UIView *)targetView {
    UIGraphicsBeginImageContext(targetView.bounds.size);
    [targetView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();  // autorelease済
    UIGraphicsEndImageContext();
    return viewImage;
}

UILabelをtargetViewに与えるとUIImageができる(上記処理)ので、そのビットマップを編集して、LEDの中心の色で(マスクで隠れる部分も含め)LEDを四角く塗りつぶす。

+ (UIImage *)createLEDImage:(UIView *)targetView {
    UIImage *image = [ImageUtil createImage:targetView];
	
    // CGImageを取得する
    CGImageRef cgImage = image.CGImage;
	
    // 画像情報を取得する
    size_t width = CGImageGetWidth(cgImage);
    size_t height = CGImageGetHeight(cgImage);
    size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
    size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage);
    size_t bytesPerPixel = bitsPerPixel / 8;
    size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage);
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(cgImage);
    bool shouldInterpolate = CGImageGetShouldInterpolate(cgImage);
    CGColorRenderingIntent intent = CGImageGetRenderingIntent(cgImage);
	
    // データプロバイダを取得する
    CGDataProviderRef dataProvider = CGImageGetDataProvider(cgImage);
	
    // ビットマップデータを取得する
    CFDataRef data = CGDataProviderCopyData(dataProvider);
    UInt8* buffer = (UInt8*)CFDataGetBytePtr(data);
	
    // ビットマップに効果を与える
    // 2 top margin, 2 bottom margin, 12 LED area, check LED center
    // check y = 8, 24, 40....
    for (int y = 8; y < height; y += 16) {
        for (int x = 8; x < width; x += 16) {
            UInt8 *checkBit = buffer + y * bytesPerRow + x * bytesPerPixel;
            // copy this color to (x-6, y-6, 12, 12)
            for (int j = y - 6; j < y + 6; j++) {
                for (int i = x - 6; i < x + 6; i++) {
                    memcpy(buffer + j * bytesPerRow + i * bytesPerPixel, checkBit, bytesPerPixel);
                }
            }
        }
    }
	
    // 効果を与えたデータを作成する
    CFDataRef effectedData = CFDataCreate(NULL, buffer, CFDataGetLength(data));
	
    // 効果を与えたデータプロバイダを作成する
    CGDataProviderRef effectedDataProvider = CGDataProviderCreateWithCFData(effectedData);
	
    // 画像を作成する
    CGImageRef effectedCgImage = CGImageCreate(
                                               width, height, 
                                               bitsPerComponent, bitsPerPixel, bytesPerRow, 
                                               colorSpace, bitmapInfo, effectedDataProvider, 
                                               NULL, shouldInterpolate, intent);

    UIImage* effectedImage = [[[UIImage alloc] initWithCGImage:effectedCgImage] autorelease];
	
    // 作成したデータを解放する
    CGImageRelease(effectedCgImage);
    CFRelease(effectedDataProvider);
    CFRelease(effectedData);
    CFRelease(data);	
	
    return effectedImage;
}

f:id:masatoshisw20:20110716100032p:image:w360

これで普通にLEDっぽい(文字の周辺部分が中心にあった場合に色が薄くなることもありますが、拘りがなければOKでしょう)

実際に動かせるプロジェクトはこちら(ImageTest.zip)に置いておきますので、ダウンロードして動かしたり、ソースを見てみてください。簡単ですよ。

ちなみに、これに通信機能や設定などを付けていったものがConnectable LED-Boardです。無料だし、気が向いたらダウンロードしてね。
#リンク先の動画が古いや・・(^^;

2011-03-07

iAdの国が増えてる

iAdのページ見ても相変わらず国情報は更新されてない(「1月にドイツで開始されます。」のままだし)んだけど、Fill Rateから見た感じ、イタリアスペインで始まってるみたい。
下記のデータは、Connectable LED-BoardのLast 7 Daysです。

f:id:masatoshisw20:20110308052050p:image
f:id:masatoshisw20:20110308052049p:image
イタリア来たっぽい
f:id:masatoshisw20:20110308052046p:image
スペインも来たっぽい
f:id:masatoshisw20:20110308052048p:image
日本いつくるの?(ノд-。)

f:id:masatoshisw20:20110308052052p:image
eCPMが0だし、カナダ試験開始?


ここからは、一般的にiAd動いてる国。
f:id:masatoshisw20:20110308052051p:image
フランス、eCPM高ぇ!
ドイツ、eCPMもっとがんばって!

f:id:masatoshisw20:20110308052045p:image
f:id:masatoshisw20:20110308052042p:image
iAd動いてる国々でここまで弱いと泣ける・・


実験的にiAd入れたけど、マジで実験にしかならなかった件。
ジュースも買えないよorz

2011-02-14

iAd実験中

iAdの効果がどんなもんか実測してみたいなーと、Connectable LED-BoardにiAd組み込んでみました。

モバイル広告の世界に広がる“iAdsはだめだ”説 - TechCrunch JAPANという記事も出たので、サンプル数少なくて微妙ですが参考までに値を紹介します。データは、iAd版が動き始めた2/5から現時点までの約10日間です。


RequestsImpressionsFill Rate
US34015144.41%
UK802531.25%
FR2305122.17%
DE3,8133779.89%
JP1,44900.00%

日本は、「2011年の早い時期にiAdの配信が可能になります。」らしいので、早く早く!(今のリクエスト数だと日本来たところで全然儲かりませんがねw)

Connection: close