UITabBarに適当なアイコン画像を使う場合のフィルター
UITabBarに置くアイコンはアルファ値しか使われないらしく、それを考慮した画像を作らないとベタ塗りになってしまいます。
今回アイコン画像をアプリ実行時にダウンロードしてくるケースのため静的リソースとして作成できず、CIFilterの組み込みフィルターを調べてみるもそれっぽいのが見当たらず、
RGBの平均をアルファ値にするフィルター(?)処理を自分で書いてみました。
【参考】
- [iPhone SDK] UIImageでピクセルを扱う | sonson@Picture&Software
- UIImageやUIImagePickerControllerの使い方について.(StackOverflowの記事の和訳) - じょにーさんのにっき
- Technical Q&A QA1509: Technical Q&A QA1509
【Before】
【After】
【フィルターのコード】
+ (UIImage*) alphalize:(UIImage*)image { CGImageRef inImage = image.CGImage; CFDataRef ref = CGDataProviderCopyData(CGImageGetDataProvider(inImage)); int length = CFDataGetLength(ref); unsigned char *inData = (unsigned char *) CFDataGetBytePtr(ref); CGContextRef context = [self createBitmapContext:inImage]; unsigned char *outData = CGBitmapContextGetData(context); for (int i = 0; i < length; i += 4) { int r = *(inData + i); int g = *(inData + i + 1); int b = *(inData + i + 2); *(outData + i + 0) = 0; *(outData + i + 1) = 0; *(outData + i + 2) = 0; *(outData + i + 3) = (r + g + b) / 3; } CGImageRef outImage = CGBitmapContextCreateImage(context); UIImage* filteredImage = [UIImage imageWithCGImage:outImage scale:image.scale orientation:UIImageOrientationUp]; CGContextRelease(context); CGImageRelease(inImage); CGImageRelease(outImage); return filteredImage; } + (CGContextRef) createBitmapContext:(CGImageRef)inImage { size_t width = CGImageGetWidth(inImage); size_t height = CGImageGetHeight(inImage); int bytesPerRow = (width * 4); int byteCount = (bytesPerRow * height); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(inImage); void* bitmapData = malloc(byteCount); CGContextRef ref = CGBitmapContextCreate(bitmapData, width, height, 8, bytesPerRow, colorSpace, alphaInfo); CGColorSpaceRelease(colorSpace); return ref; }
C全然書いたことないのでリソース解放漏れとかあるかもしれません。
ARC環境なら大丈夫なのかな。
あとアルファが後ろにある前提なのでそこは適宣。
ジェネリック型の配列を作れないことに気づいた
android.os.AsyncTaskのexecuteに可変長引数しか渡せないのですがListで渡したくなったので拡張しようと思ったのですが、
abstract class AsyncTask<Param, Progress, Result> extends android.os.AsyncTask<Param, Progress, Result> { public void execute( List<Param> params ) { Param[] array = new Param[params.size()]; this.execute( params.toArray( array ) ); } }
new Param[params.size()] のところで "Cannot create a generic array of Param" でした。ナンデ!?
Java5が出てもう少しで9年経つのか。
アイテム士アグリアスさん part.1
ゴブリン「ゴブッ!(めつぶし)」
剣士ラムザ「グワーッ!」
アイテム士アグリアス「ラムザッ!大丈夫かッ!これはひどい、早速先ほど習得した目薬を使いたいところなのだが高さ的に使いにくいので横になって私の膝に頭をのせてくれないか」
剣士ラムザ「えっ ちょっ オウフ(ボフッ)」
アイテム士アグリアス「よし、今点眼するから目を大きく開けてじっとしていくれ」
剣士ラムザ「へ、は、はひ」
[目薬] (ティ-ン)
アイテム士アグリアス「よし、成功だ。目の調子はどうだ?」
剣士ラムザ「……へ? あ、だだだ大丈夫です」(暗闇解消・MP全回復・プロテス・シェル・リレイズ・リジェネ・ヘイスト)
ゴブリン「ファーーーーーーーーーwwwwwwwwwwwwwwwwwwwwwwwww(若者に未来を託し息絶える)」
sun.security.tools.KeyTool.java
sun.security.tools.KeyTool.java
keytoolのimportcert相当のことをコード上でやる必要が出てきたので調べていたらソースが出てきた.
おそらく2578行目からの addTrustedCert() メソッドだと思う.
いやしかしこれ可読性がちょっとアレだ.