====== 絵文字の吸出し(2) ====== ===== 絵文字のコードとサイズについて ===== iPhoneの絵文字の文字コードは[[http://creation.mb.softbank.jp/web/web_pic_about.html|ここ]]が詳しいです。\\ 全部で6ページあり、1ページ分の文字数は最大で91文字です。\\ 絵文字のサイズは3G、3GSは20x20、iPhone4は40x40です。\\ 320/40=8、480/40=12、8x12=96、1画面に1ページ分の絵文字が収まります。 ===== 絵文字を一画面分描画 ===== 描画はテスト用なので0ページ目固定です。\\ シュミュレータのバージョンにより絵文字のサイズが変わります。\\ //***************************************************************************** // 絵文字を一画面分描画 //***************************************************************************** void DrawEmoji(const int page) { const static u16 CodeList[][2] = { // 絵文字のコード {0xe001,0xe05a}, {0xe101,0xe15a}, {0xe201,0xe253}, {0xe301,0xe34d}, {0xe401,0xe44c}, {0xe501,0xe537}, } ; CGRect ViewRect = [[UIScreen mainScreen] bounds] ; CGContextRef ctx = UIGraphicsGetCurrentContext() ; BOOL HighReso = [UIScreen mainScreen].scale == 1.f ? NO : YES ; if(!HighReso) { ViewRect.size.width /= 2.f ; ViewRect.size.height /= 2.f ; } CGContextSetRGBFillColor(ctx,0.f,0.f,0.f,0.f) ; CGContextFillRect(ctx,ViewRect) ; CGAffineTransform tr = HighReso ? CGAffineTransformMakeScale(2.f,2.f) : CGAffineTransformMakeScale(1.f,1.f) ; CGContextSaveGState(ctx) ; CGContextConcatCTM(ctx,tr) ; for(u16 code = CodeList[page][0] ; code <= CodeList[page][1] ; ++ code) { char str[8] ; sprintf(str,"%c%c",code & 0xff,code >> 8) ; float x = ((code & 0xff) % 8) * 20.f - 1.f ; float y = ((code & 0xff) / 8) * 20.f - 1.f ; [ [ [NSString alloc] initWithCharactersNoCopy:(unichar *)str length:1 freeWhenDone:NO ] drawAtPoint:CGPointMake(x,y) withFont:[UIFont systemFontOfSize:20] ] ; } CGContextRestoreGState(ctx) ; } //***************************************************************************** // 描画時に呼ばれる //***************************************************************************** @implementation EmojiView - (void)drawRect:(CGRect)rect { DrawEmoji(0) ; } @end ===== 絵文字を一画面分保存 ===== - 仮想画面を作成(UIGraphicsBeginImageContext)。 - 絵文字を描画 - αブレンドにより変化してしまったRGB値を元に戻す - ImageContextからUIImageを作成 - tgaで保存。 実際のセーブ処理は、「[[iphone:UIImageをTGA形式で保存する]]」を使用しています。\\ //***************************************************************************** // 絵文字を一画面分保存 //***************************************************************************** void SaveEmoji(const int page) { CGRect ViewRect = [[UIScreen mainScreen] bounds] ; BOOL HighReso = [UIScreen mainScreen].scale == 1.f ? NO : YES ; if(!HighReso) { ViewRect.size.width /= 2.f ; ViewRect.size.height /= 2.f ; } UIGraphicsBeginImageContext(ViewRect.size) ; DrawEmoji(page) ; // 絵文字を描画 CGImageRef ImgRef = UIGraphicsGetImageFromCurrentImageContext().CGImage ; CFDataRef DataRef = CGDataProviderCopyData(CGImageGetDataProvider(ImgRef)) ; u08 *data = (u08 *)CFDataGetBytePtr(DataRef) ; // αが適用された RGB 値を元に戻す for(int j = 0 ; j < CGImageGetWidth(ImgRef) * CGImageGetHeight(ImgRef) ; ++ j) { u08 alpha = data[j * 4 + 3] ; if(alpha) { data[j * 4 + 0] = min(data[j * 4 + 0] * 255 / alpha,255) ; data[j * 4 + 1] = min(data[j * 4 + 1] * 255 / alpha,255) ; data[j * 4 + 2] = min(data[j * 4 + 2] * 255 / alpha,255) ; } } CGDataProviderRef DataProv = CGDataProviderCreateWithCFData( CFDataCreate(0,data,CFDataGetLength(DataRef)) ) ; CGImageRef NewImg = CGImageCreate( CGImageGetWidth(ImgRef), CGImageGetHeight(ImgRef), CGImageGetBitsPerComponent(ImgRef), CGImageGetBitsPerPixel(ImgRef), CGImageGetBytesPerRow(ImgRef), CGImageGetColorSpace(ImgRef), CGImageGetBitmapInfo(ImgRef), DataProv, 0, CGImageGetShouldInterpolate(ImgRef), CGImageGetRenderingIntent(ImgRef) ) ; UIImage *SnapShot = [[UIImage alloc] initWithCGImage:NewImg] ; char filename[260] ; // 画像を tga で保存 sprintf(filename,"/Documents/emoji%d_%d.tga",HighReso ? 4 : 3,page) ; ImageSaveTag(filename,SnapShot) ; [SnapShot release] ; UIGraphicsEndImageContext() ; } ===== 絵文字保存処理の呼び出し ===== EmojiGetAppDelegate.mmのdidFinishLaunchingWithOptionsを以下のように書き換えます。\\ 保存のみが目的なので、保存したら終了させます。\\ デバッグ時は #if 0 にすれば描画の確認を行えます。 [window makeKeyAndVisible] ; #if 1 for(int i = 0 ; i < 6 ; ++ i) SaveEmoji(i) ; exit(0) ; #endif return YES ;