====== 絵文字の吸出し(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 ;